diff --git a/CHANGELOG.md b/CHANGELOG.md index e85eeb4d..eadc641b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,96 @@ +## [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 + +* **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 + +* **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 + +* 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 + +* **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 + +* **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 + +* **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 + +* 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 + +* **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 + +* **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.1](https://github.com/maevsi/sqitch/compare/7.0.0...7.0.1) (2025-04-26) ### Bug Fixes diff --git a/Dockerfile b/Dockerfile index d40327d3..b141eb23 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,29 +35,31 @@ 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_vibetype_password \ + /run/secrets/postgres_role_service_grafana_password \ /run/secrets/postgres_role_service_postgraphile_password \ + /run/secrets/postgres_role_service_vibetype_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/docs/onboarding/project.md b/docs/onboarding/project.md index ead4ef09..73c33ff3 100644 --- a/docs/onboarding/project.md +++ b/docs/onboarding/project.md @@ -36,7 +36,7 @@ All tests run in a containerized environment. You can add basic test data to your working directory by running: ```sh -git apply --3way test/data.patch +git apply --3way test/development/data.patch ``` Then, deploy the patch as described in the [Code Structure](#code-structure) section. @@ -44,7 +44,7 @@ Then, deploy the patch as described in the [Code Structure](#code-structure) sec To persist changes to test data, stage them and run: ```sh -git diff --staged > test/data.patch +git diff --staged > test/development/data.patch ``` ### Schema Fixture diff --git a/package.json b/package.json index c4989063..b3616268 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,13 @@ "packageManager": "pnpm@10.11.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": "7.0.1" + "version": "8.0.0-beta.10" } 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/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/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/deploy/function_upload_create.sql b/src/deploy/function_upload_create.sql deleted file mode 100644 index 9905c19a..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.account_id = 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) - 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/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/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_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_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/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/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_policy.sql b/src/deploy/table_address_policy.sql index d10c1139..d3924e59 100644 --- a/src/deploy/table_address_policy.sql +++ b/src/deploy/table_address_policy.sql @@ -5,13 +5,19 @@ GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.address TO vibetype_accou ALTER TABLE vibetype.address ENABLE ROW LEVEL SECURITY; -CREATE POLICY address ON vibetype.address FOR ALL USING ( - created_by = vibetype.invoker_account_id() +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 ( +) +WITH CHECK ( created_by = vibetype.invoker_account_id() ); 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..bb1dc29b 100644 --- a/src/deploy/table_event_favorite.sql +++ b/src/deploy/table_event_favorite.sql @@ -11,13 +11,20 @@ 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.'; --- 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 deleted file mode 100644 index 1e6a0c16..00000000 --- a/src/deploy/table_event_group.sql +++ /dev/null @@ -1,38 +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_account, vibetype_anonymous; -GRANT INSERT, 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 614bc8aa..00000000 --- a/src/deploy/table_event_grouping.sql +++ /dev/null @@ -1,29 +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_account, vibetype_anonymous; -GRANT INSERT, 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/deploy/table_event_policy.sql b/src/deploy/table_event_policy.sql index b04e4aa8..c081a3d2 100644 --- a/src/deploy/table_event_policy.sql +++ b/src/deploy/table_event_policy.sql @@ -1,51 +1,48 @@ 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 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 ( - ( - 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 ( - 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 +-- 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 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 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; --- 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() +GRANT EXECUTE ON FUNCTION vibetype_private.event_policy_select() TO vibetype_account, vibetype_anonymous; + +CREATE POLICY event_select ON vibetype.event FOR SELECT +USING ( + id IN (SELECT id FROM vibetype_private.event_policy_select()) ); 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..b9cafeed 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 created_by = 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.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/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.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 5d382699..c8d6cc23 100644 --- a/src/deploy/table_upload_policy.sql +++ b/src/deploy/table_upload_policy.sql @@ -2,36 +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, :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_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 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 --- - all uploads for the server or --- - 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_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 ( + created_by = 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' +-- Allow accounts to update their own uploads. +CREATE POLICY upload_update ON vibetype.upload FOR UPDATE +USING ( + created_by = vibetype.invoker_account_id() ); --- 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' +-- 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/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/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/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/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/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/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/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_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..eac792b5 100644 --- a/src/revert/table_address.sql +++ b/src/revert/table_address.sql @@ -1,6 +1,7 @@ BEGIN; 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 index e05854c9..1abee848 100644 --- a/src/revert/table_address_policy.sql +++ b/src/revert/table_address_policy.sql @@ -1,5 +1,5 @@ BEGIN; -DROP POLICY address ON vibetype.address; +DROP POLICY address_all 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_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/revert/table_event_policy.sql b/src/revert/table_event_policy.sql index f769fce9..10b5f26e 100644 --- a/src/revert/table_event_policy.sql +++ b/src/revert/table_event_policy.sql @@ -1,7 +1,7 @@ BEGIN; -DROP POLICY event_update ON vibetype.event; -DROP POLICY event_insert 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/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 ffe97c5a..a48d16b1 100644 --- a/src/revert/table_legal_term.sql +++ b/src/revert/table_legal_term.sql @@ -1,10 +1,11 @@ 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; 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..08ca79c6 100644 --- a/src/revert/table_upload_policy.sql +++ b/src/revert/table_upload_policy.sql @@ -1,7 +1,10 @@ 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_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/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 b/src/sqitch index 4fd6c129..b74f4ef0 100755 --- a/src/sqitch +++ b/src/sqitch @@ -79,8 +79,10 @@ 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_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" \ + --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" "$@" diff --git a/src/sqitch.plan b/src/sqitch.plan index 835f0d4f..cb81213a 100644 --- a/src/sqitch.plan +++ b/src/sqitch.plan @@ -3,44 +3,41 @@ %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. role_vibetype [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_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. +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 test_postgres] 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. 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. -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. 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. @@ -53,7 +50,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. @@ -61,7 +57,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. @@ -71,40 +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. -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. 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/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/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_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/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/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/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/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..1e3b562e 100644 --- a/src/verify/table_account_block.sql +++ b/src/verify/table_account_block.sql @@ -6,8 +6,27 @@ 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; + +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_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_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/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 04699f76..00000000 --- a/src/verify/table_account_social_network_policy.sql +++ /dev/null @@ -1,101 +0,0 @@ -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; - -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..d0d745dd 100644 --- a/src/verify/table_device.sql +++ b/src/verify/table_device.sql @@ -8,8 +8,28 @@ 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; + +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.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_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_group.sql b/src/verify/table_event_group.sql deleted file mode 100644 index 3a7975f9..00000000 --- a/src/verify/table_event_group.sql +++ /dev/null @@ -1,35 +0,0 @@ -BEGIN; - -SELECT id, - description, - is_archived, - name, - slug, - created_at, - 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'; - -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 dd74bb19..00000000 --- a/src/verify/table_event_grouping.sql +++ /dev/null @@ -1,31 +0,0 @@ -BEGIN; - -SELECT id, - event_group_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'; - -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/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..fb49c880 100644 --- a/src/verify/table_event_upload.sql +++ b/src/verify/table_event_upload.sql @@ -5,3 +5,24 @@ SELECT id, is_header_image, upload_id FROM vibetype.event_upload 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_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 07ecd853..66005c24 100644 --- a/src/verify/table_friendship.sql +++ b/src/verify/table_friendship.sql @@ -12,8 +12,27 @@ SELECT FROM vibetype.friendship WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['idx_friendship_created_by', 'idx_friendship_updated_by'] -); +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_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/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/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/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 78% rename from test/schema/schema.definition.sql rename to test/fixture/schema.definition.sql index 8723b3b2..e6341b2b 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: - -- @@ -1197,32 +1181,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 -- @@ -1944,121 +1902,36 @@ $$; ALTER FUNCTION vibetype.trigger_metadata_update_fcm() 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, - 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 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.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 --- - -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.'; - - --- --- Name: COLUMN upload.storage_key; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.storage_key IS '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''.'; - - --- --- 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: upload_create(bigint); Type: FUNCTION; Schema: vibetype; Owner: ci +-- Name: trigger_upload_insert(); Type: FUNCTION; Schema: vibetype; Owner: ci -- -CREATE FUNCTION vibetype.upload_create(size_byte bigint) RETURNS vibetype.upload - LANGUAGE plpgsql STRICT SECURITY DEFINER +CREATE FUNCTION vibetype.trigger_upload_insert() RETURNS trigger + LANGUAGE plpgsql SECURITY DEFINER AS $$ DECLARE - _upload vibetype.upload; + _current_usage BIGINT; + _quota BIGINT; BEGIN - IF (COALESCE(( - SELECT SUM(upload.size_byte) + SELECT COALESCE(SUM(size_byte), 0) + INTO _current_usage FROM vibetype.upload - WHERE upload.account_id = current_setting('jwt.claims.account_id')::UUID - ), 0) + upload_create.size_byte <= ( - SELECT upload_quota_bytes + WHERE created_by = current_setting('jwt.claims.account_id')::UUID; + + SELECT upload_quota_bytes + INTO _quota FROM vibetype_private.account - WHERE account.id = current_setting('jwt.claims.account_id')::UUID - )) THEN - INSERT INTO vibetype.upload(account_id, size_byte) - VALUES (current_setting('jwt.claims.account_id')::UUID, upload_create.size_byte) - RETURNING upload.id INTO _upload; + WHERE id = current_setting('jwt.claims.account_id')::UUID; - RETURN _upload; - ELSE + 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.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.'; - +ALTER FUNCTION vibetype.trigger_upload_insert() OWNER TO ci; -- -- Name: account_block_ids(); Type: FUNCTION; Schema: vibetype_private; Owner: ci @@ -2182,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 -- @@ -2615,1066 +2521,141 @@ COMMENT ON FUNCTION vibetype_private.trigger_audit_log_enable_multiple() IS 'Fun -- --- Name: account_block_create(uuid, uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci +-- Name: changes; Type: TABLE; Schema: sqitch; 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 || ''''; +CREATE TABLE sqitch.changes ( + change_id text NOT NULL, + script_hash text, + change text NOT NULL, + project text NOT NULL, + note text DEFAULT ''::text NOT NULL, + committed_at timestamp with time zone DEFAULT clock_timestamp() NOT NULL, + committer_name text NOT NULL, + committer_email text NOT NULL, + planned_at timestamp with time zone NOT NULL, + planner_name text NOT NULL, + planner_email text NOT NULL +); - 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(); +ALTER TABLE sqitch.changes OWNER TO ci; - RETURN _id; -END $$; +-- +-- Name: TABLE changes; Type: COMMENT; Schema: sqitch; Owner: ci +-- +COMMENT ON TABLE sqitch.changes IS 'Tracks the changes currently deployed to the database.'; -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 +-- Name: COLUMN changes.change_id; Type: COMMENT; Schema: sqitch; 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 $$; - +COMMENT ON COLUMN sqitch.changes.change_id IS 'Change primary key.'; -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 +-- Name: COLUMN changes.script_hash; Type: COMMENT; Schema: sqitch; 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; -$$; - +COMMENT ON COLUMN sqitch.changes.script_hash IS 'Deploy script SHA-1 hash.'; -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 +-- Name: COLUMN changes.change; Type: COMMENT; Schema: sqitch; 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.'; +COMMENT ON COLUMN sqitch.changes.change IS 'Name of a deployed change.'; -- --- Name: account_location_coordinates(uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci +-- Name: COLUMN changes.project; Type: COMMENT; Schema: sqitch; 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; +COMMENT ON COLUMN sqitch.changes.project IS 'Name of the Sqitch project to which the change belongs.'; - RETURN ARRAY[_latitude, _longitude]; -END; -$$; +-- +-- Name: COLUMN changes.note; Type: COMMENT; Schema: sqitch; Owner: ci +-- + +COMMENT ON COLUMN sqitch.changes.note IS 'Description of the change.'; -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 +-- Name: COLUMN changes.committed_at; Type: COMMENT; Schema: sqitch; 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'; +COMMENT ON COLUMN sqitch.changes.committed_at IS 'Date the change was deployed.'; -- --- Name: account_location_update(uuid, double precision, double precision); Type: FUNCTION; Schema: vibetype_test; Owner: ci +-- Name: COLUMN changes.committer_name; Type: COMMENT; Schema: sqitch; 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; -$$; - +COMMENT ON COLUMN sqitch.changes.committer_name IS 'Name of the user who deployed the change.'; -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 +-- Name: COLUMN changes.committer_email; Type: COMMENT; Schema: sqitch; 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).'; +COMMENT ON COLUMN sqitch.changes.committer_email IS 'Email address of the user who deployed the change.'; -- --- Name: account_registration_verified(text, text); Type: FUNCTION; Schema: vibetype_test; Owner: ci +-- Name: COLUMN changes.planned_at; Type: COMMENT; Schema: sqitch; 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); +COMMENT ON COLUMN sqitch.changes.planned_at IS 'Date the change was added to the plan.'; - 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; +-- +-- Name: COLUMN changes.planner_name; Type: COMMENT; Schema: sqitch; Owner: ci +-- + +COMMENT ON COLUMN sqitch.changes.planner_name IS 'Name of the user who planed the change.'; - PERFORM vibetype.account_email_address_verification(_verification); - RETURN _account_id; -END $$; +-- +-- Name: COLUMN changes.planner_email; Type: COMMENT; Schema: sqitch; Owner: ci +-- +COMMENT ON COLUMN sqitch.changes.planner_email IS 'Email address of the user who planned the change.'; -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 +-- Name: dependencies; Type: TABLE; Schema: sqitch; 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; +CREATE TABLE sqitch.dependencies ( + change_id text NOT NULL, + type text NOT NULL, + dependency text NOT NULL, + dependency_id text, + CONSTRAINT dependencies_check CHECK ((((type = 'require'::text) AND (dependency_id IS NOT NULL)) OR ((type = 'conflict'::text) AND (dependency_id IS NULL)))) +); + - IF _id IS NOT NULL THEN +ALTER TABLE sqitch.dependencies OWNER TO ci; - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _id || ''''; +-- +-- Name: TABLE dependencies; Type: COMMENT; Schema: sqitch; Owner: ci +-- - DELETE FROM vibetype.event WHERE created_by = _id; +COMMENT ON TABLE sqitch.dependencies IS 'Tracks the currently satisfied dependencies.'; - PERFORM vibetype.account_delete('password'); - CALL vibetype_test.set_local_superuser(); - END IF; -END $$; +-- +-- Name: COLUMN dependencies.change_id; Type: COMMENT; Schema: sqitch; Owner: ci +-- +COMMENT ON COLUMN sqitch.dependencies.change_id IS 'ID of the depending change.'; -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); - - IF _existing_count <> _expected_count THEN - RAISE EXCEPTION 'Index mismatch in schema "%". Expected: %, Found: %', schema, _expected_count, _existing_count; - END IF; -END; -$$; - - -ALTER FUNCTION vibetype_test.index_existence(indexes text[], schema text) OWNER TO ci; - --- --- Name: FUNCTION index_existence(indexes text[], schema text); Type: COMMENT; Schema: vibetype_test; 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.'; - - --- --- Name: invoker_set(uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.invoker_set(_invoker_id uuid) RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_id || ''''; -END $$; - - -ALTER FUNCTION vibetype_test.invoker_set(_invoker_id uuid) OWNER TO ci; - --- --- Name: invoker_unset(); Type: FUNCTION; Schema: vibetype_test; 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 $$; - - -ALTER FUNCTION vibetype_test.invoker_unset() OWNER TO ci; - --- --- Name: legal_term_singleton(); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.legal_term_singleton() RETURNS uuid - LANGUAGE plpgsql - 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 $$; - - -ALTER FUNCTION vibetype_test.legal_term_singleton() OWNER TO ci; - --- --- Name: set_local_superuser(); Type: PROCEDURE; Schema: vibetype_test; Owner: ci --- - -CREATE PROCEDURE vibetype_test.set_local_superuser() - LANGUAGE plpgsql - 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 $$; - - -ALTER PROCEDURE vibetype_test.set_local_superuser() OWNER TO ci; - --- --- Name: uuid_array_test(text, uuid[], uuid[]); Type: FUNCTION; Schema: vibetype_test; 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 $$; - - -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 --- - -CREATE TABLE sqitch.changes ( - change_id text NOT NULL, - script_hash text, - change text NOT NULL, - project text NOT NULL, - note text DEFAULT ''::text NOT NULL, - committed_at timestamp with time zone DEFAULT clock_timestamp() NOT NULL, - committer_name text NOT NULL, - committer_email text NOT NULL, - planned_at timestamp with time zone NOT NULL, - planner_name text NOT NULL, - planner_email text NOT NULL -); - - -ALTER TABLE sqitch.changes OWNER TO ci; - --- --- Name: TABLE changes; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON TABLE sqitch.changes IS 'Tracks the changes currently deployed to the database.'; - - --- --- Name: COLUMN changes.change_id; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.change_id IS 'Change primary key.'; - - --- --- Name: COLUMN changes.script_hash; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.script_hash IS 'Deploy script SHA-1 hash.'; - - --- --- Name: COLUMN changes.change; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.change IS 'Name of a deployed change.'; - - --- --- Name: COLUMN changes.project; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.project IS 'Name of the Sqitch project to which the change belongs.'; - - --- --- Name: COLUMN changes.note; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.note IS 'Description of the change.'; - - --- --- Name: COLUMN changes.committed_at; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.committed_at IS 'Date the change was deployed.'; - - --- --- Name: COLUMN changes.committer_name; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.committer_name IS 'Name of the user who deployed the change.'; - - --- --- Name: COLUMN changes.committer_email; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.committer_email IS 'Email address of the user who deployed the change.'; - - --- --- Name: COLUMN changes.planned_at; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.planned_at IS 'Date the change was added to the plan.'; - - --- --- Name: COLUMN changes.planner_name; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.planner_name IS 'Name of the user who planed the change.'; - - --- --- Name: COLUMN changes.planner_email; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.changes.planner_email IS 'Email address of the user who planned the change.'; - - --- --- Name: dependencies; Type: TABLE; Schema: sqitch; Owner: ci --- - -CREATE TABLE sqitch.dependencies ( - change_id text NOT NULL, - type text NOT NULL, - dependency text NOT NULL, - dependency_id text, - CONSTRAINT dependencies_check CHECK ((((type = 'require'::text) AND (dependency_id IS NOT NULL)) OR ((type = 'conflict'::text) AND (dependency_id IS NULL)))) -); - - -ALTER TABLE sqitch.dependencies OWNER TO ci; - --- --- Name: TABLE dependencies; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON TABLE sqitch.dependencies IS 'Tracks the currently satisfied dependencies.'; - - --- --- Name: COLUMN dependencies.change_id; Type: COMMENT; Schema: sqitch; Owner: ci --- - -COMMENT ON COLUMN sqitch.dependencies.change_id IS 'ID of the depending change.'; - - --- --- Name: COLUMN dependencies.type; Type: COMMENT; Schema: sqitch; Owner: ci +-- Name: COLUMN dependencies.type; Type: COMMENT; Schema: sqitch; Owner: ci -- COMMENT ON COLUMN sqitch.dependencies.type IS 'Type of dependency.'; @@ -4041,7 +3022,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 +3047,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 -- @@ -4697,293 +3696,172 @@ ALTER TABLE vibetype.event_category OWNER TO ci; -- Name: TABLE event_category; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON TABLE vibetype.event_category IS 'Event categories.'; - - --- --- Name: COLUMN event_category.id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_category.id IS 'The id of the event category.'; - - --- --- Name: COLUMN event_category.name; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_category.name IS 'A category name.'; - - --- --- Name: event_category_mapping; Type: TABLE; Schema: vibetype; Owner: ci --- - -CREATE TABLE vibetype.event_category_mapping ( - event_id uuid NOT NULL, - category_id uuid NOT NULL -); - - -ALTER TABLE vibetype.event_category_mapping OWNER TO ci; - --- --- Name: TABLE event_category_mapping; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON TABLE vibetype.event_category_mapping IS 'Mapping events to categories (M:N relationship).'; - - --- --- Name: COLUMN event_category_mapping.event_id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_category_mapping.event_id IS 'An event id.'; - - --- --- Name: COLUMN event_category_mapping.category_id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_category_mapping.category_id IS 'A category id.'; - - --- --- Name: event_favorite; Type: TABLE; Schema: vibetype; Owner: ci --- - -CREATE TABLE vibetype.event_favorite ( - id uuid DEFAULT gen_random_uuid() NOT NULL, - event_id uuid, - created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, - created_by uuid NOT NULL -); - - -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.'; - - --- --- Name: COLUMN event_favorite.id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_favorite.id IS '@omit create,update -Primary key, uniquely identifies each favorite entry.'; - - --- --- Name: COLUMN event_favorite.event_id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_favorite.event_id IS 'Reference to the event that is marked as a favorite.'; - - --- --- Name: COLUMN event_favorite.created_at; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_favorite.created_at IS '@omit create,update -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.'; - - --- --- Name: event_format; Type: TABLE; Schema: vibetype; Owner: ci --- - -CREATE TABLE vibetype.event_format ( - id uuid DEFAULT gen_random_uuid() NOT NULL, - name text NOT NULL -); - - -ALTER TABLE vibetype.event_format OWNER TO ci; - --- --- Name: TABLE event_format; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON TABLE vibetype.event_format IS 'Event formats.'; +COMMENT ON TABLE vibetype.event_category IS 'Event categories.'; -- --- Name: COLUMN event_format.id; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_category.id; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_format.id IS 'The id of the event format.'; +COMMENT ON COLUMN vibetype.event_category.id IS 'The id of the event category.'; -- --- Name: COLUMN event_format.name; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_category.name; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_format.name IS 'The name of the event format.'; +COMMENT ON COLUMN vibetype.event_category.name IS 'A category name.'; -- --- Name: event_format_mapping; Type: TABLE; Schema: vibetype; Owner: ci +-- Name: event_category_mapping; Type: TABLE; Schema: vibetype; Owner: ci -- -CREATE TABLE vibetype.event_format_mapping ( +CREATE TABLE vibetype.event_category_mapping ( event_id uuid NOT NULL, - format_id uuid NOT NULL + category_id uuid NOT NULL ); -ALTER TABLE vibetype.event_format_mapping OWNER TO ci; +ALTER TABLE vibetype.event_category_mapping OWNER TO ci; -- --- Name: TABLE event_format_mapping; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: TABLE event_category_mapping; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON TABLE vibetype.event_format_mapping IS 'Mapping events to formats (M:N relationship).'; +COMMENT ON TABLE vibetype.event_category_mapping IS 'Mapping events to categories (M:N relationship).'; -- --- Name: COLUMN event_format_mapping.event_id; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_category_mapping.event_id; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_format_mapping.event_id IS 'An event id.'; +COMMENT ON COLUMN vibetype.event_category_mapping.event_id IS 'An event id.'; -- --- Name: COLUMN event_format_mapping.format_id; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_category_mapping.category_id; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_format_mapping.format_id IS 'A format id.'; +COMMENT ON COLUMN vibetype.event_category_mapping.category_id IS 'A category id.'; -- --- Name: event_group; Type: TABLE; Schema: vibetype; Owner: ci +-- Name: event_favorite; Type: TABLE; Schema: vibetype; Owner: ci -- -CREATE TABLE vibetype.event_group ( +CREATE TABLE vibetype.event_favorite ( 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, + event_id uuid, 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))) + created_by uuid NOT NULL ); -ALTER TABLE vibetype.event_group OWNER TO ci; +ALTER TABLE vibetype.event_favorite OWNER TO ci; -- --- Name: TABLE event_group; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: TABLE event_favorite; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON TABLE vibetype.event_group IS 'A group of events.'; +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_group.id; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_favorite.id; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_group.id IS '@omit create,update -The event group''s internal id.'; +COMMENT ON COLUMN vibetype.event_favorite.id IS '@omit create +Primary key, uniquely identifies each favorite entry.'; -- --- Name: COLUMN event_group.description; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_favorite.event_id; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_group.description IS 'The event group''s description.'; +COMMENT ON COLUMN vibetype.event_favorite.event_id IS 'Reference to the event that is marked as a favorite.'; -- --- Name: COLUMN event_group.is_archived; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_favorite.created_at; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_group.is_archived IS 'Indicates whether the event group is archived.'; +COMMENT ON COLUMN vibetype.event_favorite.created_at IS '@omit create +Timestamp when the favorite was created. Defaults to the current timestamp.'; -- --- Name: COLUMN event_group.name; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_favorite.created_by; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_group.name IS 'The event group''s name.'; +COMMENT ON COLUMN vibetype.event_favorite.created_by IS 'Reference to the account that created the event favorite.'; -- --- Name: COLUMN event_group.slug; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: event_format; Type: TABLE; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_group.slug IS '@omit create,update -The event group''s name, slugified.'; +CREATE TABLE vibetype.event_format ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + name text NOT NULL +); +ALTER TABLE vibetype.event_format OWNER TO ci; + -- --- Name: COLUMN event_group.created_at; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: TABLE event_format; 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.'; +COMMENT ON TABLE vibetype.event_format IS 'Event formats.'; -- --- Name: COLUMN event_group.created_by; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_format.id; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_group.created_by IS 'The event group creator''s id.'; +COMMENT ON COLUMN vibetype.event_format.id IS 'The id of the event format.'; -- --- Name: event_grouping; Type: TABLE; Schema: vibetype; Owner: ci +-- Name: COLUMN event_format.name; Type: COMMENT; 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 -); - +COMMENT ON COLUMN vibetype.event_format.name IS 'The name of the event format.'; -ALTER TABLE vibetype.event_grouping OWNER TO ci; -- --- Name: TABLE event_grouping; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: event_format_mapping; Type: TABLE; Schema: vibetype; Owner: ci -- -COMMENT ON TABLE vibetype.event_grouping IS 'A bidirectional mapping between an event and an event group.'; +CREATE TABLE vibetype.event_format_mapping ( + event_id uuid NOT NULL, + format_id uuid NOT NULL +); +ALTER TABLE vibetype.event_format_mapping OWNER TO ci; + -- --- Name: COLUMN event_grouping.id; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: TABLE event_format_mapping; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_grouping.id IS '@omit create,update -The event grouping''s internal id.'; +COMMENT ON TABLE vibetype.event_format_mapping IS 'Mapping events to formats (M:N relationship).'; -- --- Name: COLUMN event_grouping.event_group_id; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_format_mapping.event_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.'; +COMMENT ON COLUMN vibetype.event_format_mapping.event_id IS 'An event id.'; -- --- Name: COLUMN event_grouping.event_id; Type: COMMENT; Schema: vibetype; Owner: ci +-- Name: COLUMN event_format_mapping.format_id; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_grouping.event_id IS 'The event grouping''s internal event id.'; +COMMENT ON COLUMN vibetype.event_format_mapping.format_id IS 'A format id.'; -- @@ -5474,6 +4352,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 -- @@ -6177,38 +5137,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 -- @@ -6634,6 +5562,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 -- @@ -6896,30 +5831,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 -- @@ -7073,11 +5984,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; -- @@ -7093,24 +6004,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 --- - -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 +-- Name: account_block account_block_all; 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())); -- @@ -7120,24 +6017,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 --- - -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 +-- Name: account_preference_event_category account_preference_event_category_all; 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())); -- @@ -7147,24 +6030,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())); -- @@ -7174,24 +6043,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())); -- @@ -7208,24 +6063,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 --- - -CREATE POLICY account_social_network_delete ON vibetype.account_social_network FOR DELETE 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_all; 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())); +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_update; 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_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); -- @@ -7248,10 +6096,11 @@ 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()) 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())); @@ -7302,10 +6151,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())); -- @@ -7315,69 +6164,55 @@ CREATE POLICY device ON vibetype.device USING ((created_by = vibetype.invoker_ac ALTER TABLE vibetype.event ENABLE ROW LEVEL SECURITY; -- --- Name: event_category_mapping; Type: ROW SECURITY; Schema: vibetype; Owner: ci --- - -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 - FROM vibetype.event - 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 +-- Name: event event_all; 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 - FROM vibetype.event - WHERE (event.id = event_category_mapping.event_id)) = vibetype.invoker_account_id()))); +CREATE POLICY event_all ON vibetype.event USING ((created_by = vibetype.invoker_account_id())); -- --- Name: event_category_mapping event_category_mapping_select; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: event_category_mapping; Type: ROW SECURITY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_category_mapping_select ON vibetype.event_category_mapping FOR SELECT USING ((event_id IN ( SELECT event.id - FROM vibetype.event))); - +ALTER TABLE vibetype.event_category_mapping ENABLE ROW LEVEL SECURITY; -- --- Name: event event_delete; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: event_category_mapping event_category_mapping_delete; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_delete ON vibetype.event FOR DELETE USING ((created_by = vibetype.invoker_account_id())); +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())); -- --- Name: event_favorite; Type: ROW SECURITY; Schema: vibetype; Owner: ci +-- Name: event_category_mapping event_category_mapping_insert; Type: POLICY; Schema: vibetype; Owner: ci -- -ALTER TABLE vibetype.event_favorite ENABLE ROW LEVEL SECURITY; +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())); + -- --- Name: event_favorite event_favorite_delete; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: event_category_mapping event_category_mapping_select; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_favorite_delete ON vibetype.event_favorite FOR DELETE USING ((created_by = vibetype.invoker_account_id())); +CREATE POLICY event_category_mapping_select ON vibetype.event_category_mapping FOR SELECT USING ((event_id IN ( SELECT event.id + FROM vibetype.event))); -- --- Name: event_favorite event_favorite_insert; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: event_favorite; Type: ROW SECURITY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_favorite_insert ON vibetype.event_favorite FOR INSERT WITH CHECK ((created_by = vibetype.invoker_account_id())); - +ALTER TABLE vibetype.event_favorite ENABLE ROW LEVEL SECURITY; -- --- 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())); -- @@ -7412,25 +6247,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 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 -- @@ -7441,22 +6257,15 @@ 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())); -- -- 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 (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()))); +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)))); -- @@ -7482,7 +6291,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()))))); -- @@ -7594,17 +6403,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 --- - -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 +-- Name: legal_term_acceptance legal_term_acceptance_all; 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())); -- @@ -7621,17 +6423,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); -- @@ -7642,58 +6444,58 @@ CREATE POLICY profile_picture_select ON vibetype.profile_picture FOR SELECT USIN -- --- Name: profile_picture profile_picture_update; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: report; Type: ROW SECURITY; 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()))); - +ALTER TABLE vibetype.report ENABLE ROW LEVEL SECURITY; -- --- Name: report; Type: ROW SECURITY; Schema: vibetype; Owner: ci +-- Name: report report_all; Type: POLICY; Schema: vibetype; Owner: ci -- -ALTER TABLE vibetype.report ENABLE ROW LEVEL SECURITY; +CREATE POLICY report_all ON vibetype.report USING ((created_by = vibetype.invoker_account_id())); + -- --- Name: report report_insert; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: upload; Type: ROW SECURITY; 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()))); - +ALTER TABLE vibetype.upload ENABLE ROW LEVEL SECURITY; -- --- Name: report report_select; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: upload upload_delete; 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 upload_delete ON vibetype.upload FOR DELETE USING ((created_by = vibetype.invoker_account_id())); -- --- Name: upload; Type: ROW SECURITY; Schema: vibetype; Owner: ci +-- Name: upload upload_insert; Type: POLICY; Schema: vibetype; Owner: ci -- -ALTER TABLE vibetype.upload ENABLE ROW LEVEL SECURITY; +CREATE POLICY upload_insert ON vibetype.upload FOR INSERT WITH CHECK ((created_by = vibetype.invoker_account_id())); + -- --- Name: upload upload_delete_using; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: upload upload_select; 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_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_select_using; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: upload upload_service_vibetype_all; 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 - FROM vibetype.profile_picture)))); +CREATE POLICY upload_service_vibetype_all ON vibetype.upload TO vibetype USING (true); -- --- Name: upload upload_update_using; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: upload upload_update; 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)); +CREATE POLICY upload_update ON vibetype.upload FOR UPDATE USING ((created_by = vibetype.invoker_account_id())); -- @@ -7719,11 +6521,10 @@ GRANT USAGE ON SCHEMA vibetype TO vibetype; -- --- Name: SCHEMA vibetype_test; Type: ACL; Schema: -; Owner: ci +-- Name: SCHEMA vibetype_private; Type: ACL; Schema: -; Owner: ci -- -GRANT USAGE ON SCHEMA vibetype_test TO vibetype_anonymous; -GRANT USAGE ON SCHEMA vibetype_test TO vibetype_account; +GRANT USAGE ON SCHEMA vibetype_private TO grafana; -- @@ -8083,8 +6884,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; -- @@ -8104,15 +6905,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 -- @@ -8268,20 +7060,10 @@ REVOKE ALL ON FUNCTION vibetype.trigger_metadata_update_fcm() 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; - - --- --- Name: FUNCTION upload_create(size_byte bigint); Type: ACL; Schema: vibetype; Owner: ci +-- Name: FUNCTION trigger_upload_insert(); 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; +REVOKE ALL ON FUNCTION vibetype.trigger_upload_insert() FROM PUBLIC; -- @@ -8316,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 -- @@ -8388,255 +7179,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 -- @@ -8702,8 +7244,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; -- @@ -8752,35 +7294,19 @@ 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,INSERT,DELETE,UPDATE ON TABLE vibetype.event_group TO vibetype_account; -GRANT SELECT ON TABLE vibetype.event_group TO vibetype_anonymous; - - --- --- 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; - - -- -- 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; -- @@ -8817,8 +7343,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; @@ -8829,6 +7355,22 @@ 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 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 -- 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 73% rename from src/verify/test_postgres.sql rename to test/logic/scenario/database/index.sql index 0b01e604..f397cb56 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,34 @@ 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_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 ['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