From 4fc4b03b024e56cfa706d8fc782567410bb0d620 Mon Sep 17 00:00:00 2001 From: Inian Parameshwaran Date: Thu, 18 Mar 2021 13:13:14 +0530 Subject: [PATCH] fix: change schema to speed up queries bucket_id is no longer uuid and is user configurable. By default it is the same as bucket_name --- src/routes/bucket/createBucket.ts | 7 ++++ src/routes/object/copyObject.ts | 15 +------ src/routes/object/createObject.ts | 25 ++---------- src/routes/object/deleteObject.ts | 22 +--------- src/routes/object/deleteObjects.ts | 17 +------- src/routes/object/getObject.ts | 14 +------ src/routes/object/getSignedURL.ts | 11 +---- src/routes/object/renameObject.ts | 23 +---------- src/routes/object/updateObject.ts | 26 ++---------- src/test/bucket.test.ts | 20 +++++----- src/test/db/02-storage-schema.sql | 8 ++-- src/test/db/03-dummy-data.sql | 64 +++++++++++++++--------------- 12 files changed, 70 insertions(+), 182 deletions(-) diff --git a/src/routes/bucket/createBucket.ts b/src/routes/bucket/createBucket.ts index 32bebca1..065866f5 100644 --- a/src/routes/bucket/createBucket.ts +++ b/src/routes/bucket/createBucket.ts @@ -8,6 +8,7 @@ const createBucketBodySchema = { type: 'object', properties: { name: { type: 'string' }, + id: { type: 'string' }, }, required: ['name'], } as const @@ -37,11 +38,17 @@ export default async function routes(fastify: FastifyInstance) { const owner = await getOwner(jwt) const { name: bucketName } = request.body + let id = request.body.id + if (!id) { + //by default set the id as the name of the bucket + id = bucketName + } const { data: results, error, status } = await postgrest .from('buckets') .insert([ { + id, name: bucketName, owner, }, diff --git a/src/routes/object/copyObject.ts b/src/routes/object/copyObject.ts index 43acf986..069b5d32 100644 --- a/src/routes/object/copyObject.ts +++ b/src/routes/object/copyObject.ts @@ -51,10 +51,10 @@ export default async function routes(fastify: FastifyInstance) { const postgrest = getPostgrestClient(jwt) const objectResponse = await postgrest .from('objects') - .select('*, buckets(*)') + .select('*') .match({ name: sourceKey, - 'buckets.name': bucketName, + bucket_id: bucketName, }) .single() @@ -66,17 +66,6 @@ export default async function routes(fastify: FastifyInstance) { const { data: origObject } = objectResponse console.log('origObject', origObject) - if (!origObject.buckets) { - // @todo why is this check necessary? - // if corresponding bucket is not found, i want the object also to not be returned - // is it cos of https://github.com/PostgREST/postgrest/issues/1075 ? - return response.status(400).send({ - statusCode: '404', - error: 'Not found', - message: 'The requested bucket was not found', - }) - } - const newObject = Object.assign({}, origObject, { name: destinationKey, id: undefined, diff --git a/src/routes/object/createObject.ts b/src/routes/object/createObject.ts index f8342e33..e1657803 100644 --- a/src/routes/object/createObject.ts +++ b/src/routes/object/createObject.ts @@ -2,7 +2,7 @@ import { FastifyInstance } from 'fastify' import { getPostgrestClient, getOwner, transformPostgrestError } from '../../utils' import { uploadObject, initClient, deleteObject } from '../../utils/s3' import { getConfig } from '../../utils/config' -import { Obj, Bucket, AuthenticatedRequest } from '../../types/types' +import { Obj, AuthenticatedRequest } from '../../types/types' import { FromSchema } from 'json-schema-to-ts' const { region, projectRef, globalS3Bucket, globalS3Endpoint, serviceKey } = getConfig() @@ -67,25 +67,6 @@ export default async function routes(fastify: FastifyInstance) { message: err.message, }) } - // @todo how to merge these into one query? - // i can create a view and add INSTEAD OF triggers..is that the way to do it? - const bucketResponse = await postgrest - .from('buckets') - .select('id') - .eq('name', bucketName) - .single() - - if (bucketResponse.error) { - const { error } = bucketResponse - console.log(error) - return response.status(400).send({ - statusCode: '404', - error: 'Not found', - message: 'The requested bucket was not found', - }) - } - - const { data: bucket } = bucketResponse const { data: results, error, status } = await postgrest .from('objects') @@ -94,7 +75,7 @@ export default async function routes(fastify: FastifyInstance) { { name: objectName, owner: owner, - bucket_id: bucket.id, + bucket_id: bucketName, metadata: { mimetype: data.mimetype, cacheControl, @@ -136,7 +117,7 @@ export default async function routes(fastify: FastifyInstance) { .delete() .match({ name: objectName, - bucket_id: bucket.id, + bucket_id: bucketName, }) .single() await deleteObject(client, globalS3Bucket, s3Key) diff --git a/src/routes/object/deleteObject.ts b/src/routes/object/deleteObject.ts index 24fc6f74..d9459b26 100644 --- a/src/routes/object/deleteObject.ts +++ b/src/routes/object/deleteObject.ts @@ -2,7 +2,7 @@ import { FastifyInstance } from 'fastify' import { getPostgrestClient, transformPostgrestError } from '../../utils' import { deleteObject, initClient } from '../../utils/s3' import { getConfig } from '../../utils/config' -import { Obj, Bucket, AuthenticatedRequest } from '../../types/types' +import { Obj, AuthenticatedRequest } from '../../types/types' import { FromSchema } from 'json-schema-to-ts' const { region, projectRef, globalS3Bucket, globalS3Endpoint } = getConfig() @@ -48,24 +48,6 @@ export default async function routes(fastify: FastifyInstance) { const objectName = request.params['*'] const postgrest = getPostgrestClient(jwt) - // @todo how to merge these into one query? - const bucketResponse = await postgrest - .from('buckets') - .select('id') - .eq('name', bucketName) - .single() - - if (bucketResponse.error) { - const { error } = bucketResponse - console.log(error) - return response.status(400).send({ - statusCode: '404', - error: 'Not found', - message: 'The requested bucket was not found', - }) - } - console.log(bucketResponse.body) - const { data: bucket } = bucketResponse // todo what if objectName is * or something const objectResponse = await postgrest @@ -73,7 +55,7 @@ export default async function routes(fastify: FastifyInstance) { .delete() .match({ name: objectName, - bucket_id: bucket.id, + bucket_id: bucketName, }) .single() diff --git a/src/routes/object/deleteObjects.ts b/src/routes/object/deleteObjects.ts index c2339663..ba7698c0 100644 --- a/src/routes/object/deleteObjects.ts +++ b/src/routes/object/deleteObjects.ts @@ -55,26 +55,11 @@ export default async function routes(fastify: FastifyInstance) { const prefixes = request.body['prefixes'] const postgrest = getPostgrestClient(jwt) - // @todo how to merge these into one query? - const { data: bucket, error: bucketError } = await postgrest - .from('buckets') - .select('id') - .eq('name', bucketName) - .single() - - console.log(bucket, bucketError) - if (bucketError) { - return response.status(400).send({ - statusCode: '404', - error: 'Not found', - message: 'The requested bucket was not found', - }) - } const objectResponse = await postgrest .from('objects') .delete() - .eq('bucket_id', bucket.id) + .eq('bucket_id', bucketName) .in('name', prefixes) if (objectResponse.error) { diff --git a/src/routes/object/getObject.ts b/src/routes/object/getObject.ts index 6a7b0716..9ab6d572 100644 --- a/src/routes/object/getObject.ts +++ b/src/routes/object/getObject.ts @@ -44,10 +44,10 @@ export default async function routes(fastify: FastifyInstance) { const objectResponse = await postgrest .from('objects') - .select('*, buckets(*)') + .select('*') .match({ name: objectName, - 'buckets.name': bucketName, + bucket_id: bucketName, }) .single() @@ -56,16 +56,6 @@ export default async function routes(fastify: FastifyInstance) { console.log(error) return response.status(400).send(transformPostgrestError(error, status)) } - const { data: results } = objectResponse - - if (!results.buckets) { - // @todo why is this check necessary? - return response.status(400).send({ - statusCode: 404, - error: 'Not found', - message: 'The requested bucket was not found', - }) - } // send the object from s3 const s3Key = `${projectRef}/${bucketName}/${objectName}` diff --git a/src/routes/object/getSignedURL.ts b/src/routes/object/getSignedURL.ts index 1ecaae8f..44687749 100644 --- a/src/routes/object/getSignedURL.ts +++ b/src/routes/object/getSignedURL.ts @@ -59,7 +59,7 @@ export default async function routes(fastify: FastifyInstance) { .select('*, buckets(*)') .match({ name: objectName, - 'buckets.name': bucketName, + bucket_id: bucketName, }) .single() @@ -71,15 +71,6 @@ export default async function routes(fastify: FastifyInstance) { const { data: results } = objectResponse console.log(results) - if (!results.buckets) { - // @todo why is this check necessary? - return response.status(400).send({ - statusCode: '404', - error: 'Not found', - message: 'The requested bucket was not found', - }) - } - console.log(`going to sign ${request.url}`) const urlParts = request.url.split('/') const urlToSign = decodeURI(urlParts.splice(3).join('/')) diff --git a/src/routes/object/renameObject.ts b/src/routes/object/renameObject.ts index 8f705580..1ad2093b 100644 --- a/src/routes/object/renameObject.ts +++ b/src/routes/object/renameObject.ts @@ -2,7 +2,7 @@ import { FastifyInstance } from 'fastify' import { getPostgrestClient, transformPostgrestError } from '../../utils' import { initClient, copyObject, deleteObject } from '../../utils/s3' import { getConfig } from '../../utils/config' -import { Obj, Bucket, AuthenticatedRequest } from '../../types/types' +import { Obj, AuthenticatedRequest } from '../../types/types' import { FromSchema } from 'json-schema-to-ts' const { region, projectRef, globalS3Bucket, globalS3Endpoint } = getConfig() @@ -49,25 +49,6 @@ export default async function routes(fastify: FastifyInstance) { const { destinationKey, sourceKey, bucketName } = request.body const postgrest = getPostgrestClient(jwt) - // @todo how to merge these into one query? - const bucketResponse = await postgrest - .from('buckets') - .select('id') - .eq('name', bucketName) - .single() - - if (bucketResponse.error) { - const { error } = bucketResponse - console.log(error) - return response.status(400).send({ - statusCode: '404', - error: 'Not found', - message: 'The requested bucket was not found', - }) - } - - const { data: bucket } = bucketResponse - console.log(bucket) const objectResponse = await postgrest .from('objects') @@ -75,7 +56,7 @@ export default async function routes(fastify: FastifyInstance) { last_accessed_at: new Date().toISOString(), name: destinationKey, }) - .match({ bucket_id: bucket.id, name: sourceKey }) + .match({ bucket_id: bucketName, name: sourceKey }) .single() if (objectResponse.error) { diff --git a/src/routes/object/updateObject.ts b/src/routes/object/updateObject.ts index d4454fb2..a75f9b1c 100644 --- a/src/routes/object/updateObject.ts +++ b/src/routes/object/updateObject.ts @@ -2,7 +2,7 @@ import { FastifyInstance } from 'fastify' import { getPostgrestClient, getOwner, transformPostgrestError } from '../../utils' import { uploadObject, initClient } from '../../utils/s3' import { getConfig } from '../../utils/config' -import { Obj, Bucket, AuthenticatedRequest } from '../../types/types' +import { Obj, AuthenticatedRequest } from '../../types/types' import { FromSchema } from 'json-schema-to-ts' const { region, projectRef, globalS3Bucket, globalS3Endpoint } = getConfig() @@ -47,32 +47,14 @@ export default async function routes(fastify: FastifyInstance) { const data = await request.file() /* @ts-expect-error: https://github.com/aws/aws-sdk-js-v3/issues/2085 */ const cacheTime = data.fields.cacheControl?.value - const cacheControl: string = `max-age=${cacheTime}` ?? 'no-cache' + // @todo maintain the old cache time if nothing is provided here + const cacheControl: string = cacheTime ? `max-age=${cacheTime}` : 'no-cache' const { bucketName } = request.params const objectName = request.params['*'] const postgrest = getPostgrestClient(jwt) const owner = await getOwner(jwt) - // @todo how to merge these into one query? - const bucketResponse = await postgrest - .from('buckets') - .select('id') - .eq('name', bucketName) - .single() - - if (bucketResponse.error) { - const { error } = bucketResponse - console.log(error) - return response.status(400).send({ - statusCode: '404', - error: 'Not found', - message: 'The requested bucket was not found', - }) - } - - const { data: bucket } = bucketResponse - console.log(bucket) const objectResponse = await postgrest .from('objects') @@ -84,7 +66,7 @@ export default async function routes(fastify: FastifyInstance) { cacheControl, }, }) - .match({ bucket_id: bucket.id, name: objectName }) + .match({ bucket_id: bucketName, name: objectName }) .single() if (objectResponse.error) { diff --git a/src/test/bucket.test.ts b/src/test/bucket.test.ts index 1d1e6d55..c78e49e1 100644 --- a/src/test/bucket.test.ts +++ b/src/test/bucket.test.ts @@ -30,7 +30,7 @@ beforeEach(() => { // @todo add RLS tests for buckets describe('testing GET bucket', () => { test('user is able to get bucket details', async () => { - const bucketId = '7078bc23-9dd6-460d-8b93-082254fee63a' + const bucketId = 'bucket2' const response = await app().inject({ method: 'GET', url: `/bucket/${bucketId}`, @@ -46,7 +46,7 @@ describe('testing GET bucket', () => { test('user is not able to get bucket details without Auth header', async () => { const response = await app().inject({ method: 'GET', - url: '/bucket/7078bc23-9dd6-460d-8b93-082254fee63a', + url: '/bucket/bucket2', }) expect(response.statusCode).toBe(400) }) @@ -136,7 +136,7 @@ describe('testing POST bucket', () => { describe('testing DELETE bucket', () => { test('user is able to delete a bucket', async () => { - const bucketId = 'e29843e6-047e-4b1f-9906-20cc06f4aad4' + const bucketId = 'bucket4' const response = await app().inject({ method: 'DELETE', url: `/bucket/${bucketId}`, @@ -150,7 +150,7 @@ describe('testing DELETE bucket', () => { }) test('user is not able to delete bucket without Auth header', async () => { - const bucketId = '7206ba57-513a-4181-971a-feca9ef45862' + const bucketId = 'bucket5' const response = await app().inject({ method: 'DELETE', url: `/bucket/${bucketId}`, @@ -159,7 +159,7 @@ describe('testing DELETE bucket', () => { }) test('user is not able to delete bucket a non empty bucket', async () => { - const bucketId = '7078bc23-9dd6-460d-8b93-082254fee63a' + const bucketId = 'bucket2' const response = await app().inject({ method: 'DELETE', url: `/bucket/${bucketId}`, @@ -171,7 +171,7 @@ describe('testing DELETE bucket', () => { }) test('user is not able to delete a non-existent bucket', async () => { - const bucketId = '45EF6716-AAB9-48B8-8FF0-204CBB44F1A2' + const bucketId = 'notfound' const response = await app().inject({ method: 'DELETE', url: `/bucket/${bucketId}`, @@ -185,7 +185,7 @@ describe('testing DELETE bucket', () => { describe('testing EMPTY bucket', () => { test('user is able to empty a bucket', async () => { - const bucketId = 'a916b415-3639-4885-a3d7-256593098ba5' + const bucketId = 'bucket3' const response = await app().inject({ method: 'POST', url: `/bucket/${bucketId}/empty`, @@ -199,7 +199,7 @@ describe('testing EMPTY bucket', () => { }) test('user is not able to empty a bucket without Auth Header', async () => { - const bucketId = 'a916b415-3639-4885-a3d7-256593098ba5' + const bucketId = 'bucket3' const response = await app().inject({ method: 'POST', url: `/bucket/${bucketId}/empty`, @@ -208,7 +208,7 @@ describe('testing EMPTY bucket', () => { }) test('user is not able to empty a non existent bucket', async () => { - const bucketId = '7D154487-EF3B-4F6B-A259-F652B98F29D8' + const bucketId = 'notfound' const response = await app().inject({ method: 'POST', url: `/bucket/${bucketId}/empty`, @@ -220,7 +220,7 @@ describe('testing EMPTY bucket', () => { }) test('user is able to empty an already empty bucket', async () => { - const bucketId = '7206ba57-513a-4181-971a-feca9ef45862' + const bucketId = 'bucket5' const response = await app().inject({ method: 'POST', url: `/bucket/${bucketId}/empty`, diff --git a/src/test/db/02-storage-schema.sql b/src/test/db/02-storage-schema.sql index b1b05364..6e5a8131 100644 --- a/src/test/db/02-storage-schema.sql +++ b/src/test/db/02-storage-schema.sql @@ -1,7 +1,7 @@ DROP TABLE IF EXISTS "public"."buckets"; CREATE TABLE "public"."buckets" ( - "id" uuid NOT NULL DEFAULT extensions.uuid_generate_v4(), - "name" text, + "id" text not NULL, + "name" text NOT NULL, "owner" uuid, "created_at" timestamptz DEFAULT now(), "updated_at" timestamptz DEFAULT now(), @@ -13,7 +13,7 @@ CREATE UNIQUE INDEX "bname" ON "public"."buckets" USING BTREE ("name"); DROP TABLE IF EXISTS "public"."objects"; CREATE TABLE "public"."objects" ( "id" uuid NOT NULL DEFAULT extensions.uuid_generate_v4(), - "bucket_id" uuid, + "bucket_id" text, "name" text, "owner" uuid, "created_at" timestamptz DEFAULT now(), @@ -83,7 +83,7 @@ CREATE OR REPLACE FUNCTION public.search(prefix text, bucketname text, limits in LANGUAGE plpgsql AS $function$ DECLARE -_bucketId uuid; +_bucketId text; BEGIN select buckets."id" from buckets where buckets.name=bucketname limit 1 into _bucketId; return query diff --git a/src/test/db/03-dummy-data.sql b/src/test/db/03-dummy-data.sql index 4c45630f..f11fd4f2 100644 --- a/src/test/db/03-dummy-data.sql +++ b/src/test/db/03-dummy-data.sql @@ -6,41 +6,41 @@ INSERT INTO "auth"."users" ("instance_id", "id", "aud", "role", "email", "encryp -- insert buckets INSERT INTO "public"."buckets" ("id", "name", "owner", "created_at", "updated_at") VALUES -('7078bc23-9dd6-460d-8b93-082254fee63a', 'bucket2', '4d56e902-f0a0-4662-8448-a4d9e643c142', '2021-02-17 04:43:32.770206+00', '2021-02-17 04:43:32.770206+00'), -('A916B415-3639-4885-A3D7-256593098BA5', 'bucket3', '4d56e902-f0a0-4662-8448-a4d9e643c142', '2021-02-17 04:43:32.770206+00', '2021-02-17 04:43:32.770206+00'), -('e29843e6-047e-4b1f-9906-20cc06f4aad4', 'bucket4', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-25 09:23:01.58385+00', '2021-02-25 09:23:01.58385+00'), -('7206ba57-513a-4181-971a-feca9ef45862', 'bucket5', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-27 03:04:25.6386+00', '2021-02-27 03:04:25.6386+00'); +('bucket2', 'bucket2', '4d56e902-f0a0-4662-8448-a4d9e643c142', '2021-02-17 04:43:32.770206+00', '2021-02-17 04:43:32.770206+00'), +('bucket3', 'bucket3', '4d56e902-f0a0-4662-8448-a4d9e643c142', '2021-02-17 04:43:32.770206+00', '2021-02-17 04:43:32.770206+00'), +('bucket4', 'bucket4', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-25 09:23:01.58385+00', '2021-02-25 09:23:01.58385+00'), +('bucket5', 'bucket5', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-27 03:04:25.6386+00', '2021-02-27 03:04:25.6386+00'); -- insert objects INSERT INTO "public"."objects" ("id", "bucket_id", "name", "owner", "created_at", "updated_at", "last_accessed_at", "metadata") VALUES -('03e458f9-892f-4db2-8cb9-d3401a689e25', '7078bc23-9dd6-460d-8b93-082254fee63a', 'public/sadcat-upload23.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-04 08:26:08.553748+00', '2021-03-04 08:26:08.553748+00', '2021-03-04 08:26:08.553748+00', '{"mimetype": "image/svg+xml"}'), -('070825af-a11d-44fe-9f1d-abdc76f686f2', '7078bc23-9dd6-460d-8b93-082254fee63a', 'public/sadcat-upload.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-02 16:31:11.115996+00', '2021-03-02 16:31:11.115996+00', '2021-03-02 16:31:11.115996+00', '{"mimetype": "image/png"}'), -('0cac5609-11e1-4f21-b486-d0eeb60909f6', '7078bc23-9dd6-460d-8b93-082254fee63a', 'curlimage.jpg', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-23 11:05:16.625075+00', '2021-02-23 11:05:16.625075+00', '2021-02-23 11:05:16.625075+00', NULL), -('147c6795-94d5-4008-9d81-f7ba3b4f8a9f', '7078bc23-9dd6-460d-8b93-082254fee63a', 'folder/only_uid.jpg', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-17 10:36:01.504227+00', '2021-02-17 11:03:03.049618+00', '2021-02-17 10:36:01.504227+00', NULL), -('65a3aa9c-0ff2-4adc-85d0-eab673c27443', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/casestudy.png', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-17 10:42:19.366559+00', '2021-02-17 11:03:30.025116+00', '2021-02-17 10:42:19.366559+00', NULL), -('10ABE273-D77A-4BDA-B410-6FC0CA3E6ADC', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/cat.jpg', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-17 10:42:19.366559+00', '2021-02-17 11:03:30.025116+00', '2021-02-17 10:42:19.366559+00', NULL), -('1edccac7-0876-4e9f-89da-a08d2a5f654b', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/delete.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-02 16:31:11.115996+00', '2021-03-02 16:31:11.115996+00', '2021-03-02 16:31:11.115996+00', '{"mimetype": "image/png"}'), -('1a911f3c-8c1d-4661-93c1-8e065e4d757e', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/delete1.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('372d5d74-e24d-49dc-abe8-47d7eb226a2e', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/delete-multiple1.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('34811c1b-85e5-4eb6-a5e3-d607b2f6986e', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/delete-multiple2.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('45950ff2-d3a8-4add-8e49-bafc01198340', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/delete-multiple3.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('469b0216-5419-41f6-9a37-2abfd7fad29c', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/delete-multiple4.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('55930619-a668-4dbc-aea3-b93dfe101e7f', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/delete-multiple7.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('D1CE4E4F-03E2-473D-858B-301D7989B581', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/rename-orig.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('222b3d1e-bc17-414c-b336-47894aa4d697', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/rename-orig-2.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('8f7d643d-1e82-4d39-ae39-d9bd6b0cfe9c', '7078bc23-9dd6-460d-8b93-082254fee63a', 'authenticated/rename-orig-3.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), -('8377527d-3518-4dc8-8290-c6926470e795', '7078bc23-9dd6-460d-8b93-082254fee63a', 'folder/subfolder/public-all-permissions.png', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-17 10:26:42.791214+00', '2021-02-17 11:03:30.025116+00', '2021-02-17 10:26:42.791214+00', NULL), -('b39ae4ab-802b-4c42-9271-3f908c34363c', '7078bc23-9dd6-460d-8b93-082254fee63a', 'private/sadcat-upload3.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '{"mimetype": "image/svg+xml"}'), -('8098E1AC-C744-4368-86DF-71B60CCDE221', 'A916B415-3639-4885-A3D7-256593098BA5', 'sadcat-upload3.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '{"mimetype": "image/svg+xml"}'), -('D3EB488E-94F4-46CD-86D3-242C13B95BAC', 'A916B415-3639-4885-A3D7-256593098BA5', 'sadcat-upload2.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '{"mimetype": "image/svg+xml"}'); +('03e458f9-892f-4db2-8cb9-d3401a689e25', 'bucket2', 'public/sadcat-upload23.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-04 08:26:08.553748+00', '2021-03-04 08:26:08.553748+00', '2021-03-04 08:26:08.553748+00', '{"mimetype": "image/svg+xml"}'), +('070825af-a11d-44fe-9f1d-abdc76f686f2', 'bucket2', 'public/sadcat-upload.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-02 16:31:11.115996+00', '2021-03-02 16:31:11.115996+00', '2021-03-02 16:31:11.115996+00', '{"mimetype": "image/png"}'), +('0cac5609-11e1-4f21-b486-d0eeb60909f6', 'bucket2', 'curlimage.jpg', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-23 11:05:16.625075+00', '2021-02-23 11:05:16.625075+00', '2021-02-23 11:05:16.625075+00', NULL), +('147c6795-94d5-4008-9d81-f7ba3b4f8a9f', 'bucket2', 'folder/only_uid.jpg', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-17 10:36:01.504227+00', '2021-02-17 11:03:03.049618+00', '2021-02-17 10:36:01.504227+00', NULL), +('65a3aa9c-0ff2-4adc-85d0-eab673c27443', 'bucket2', 'authenticated/casestudy.png', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-17 10:42:19.366559+00', '2021-02-17 11:03:30.025116+00', '2021-02-17 10:42:19.366559+00', NULL), +('10ABE273-D77A-4BDA-B410-6FC0CA3E6ADC', 'bucket2', 'authenticated/cat.jpg', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-17 10:42:19.366559+00', '2021-02-17 11:03:30.025116+00', '2021-02-17 10:42:19.366559+00', NULL), +('1edccac7-0876-4e9f-89da-a08d2a5f654b', 'bucket2', 'authenticated/delete.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-02 16:31:11.115996+00', '2021-03-02 16:31:11.115996+00', '2021-03-02 16:31:11.115996+00', '{"mimetype": "image/png"}'), +('1a911f3c-8c1d-4661-93c1-8e065e4d757e', 'bucket2', 'authenticated/delete1.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('372d5d74-e24d-49dc-abe8-47d7eb226a2e', 'bucket2', 'authenticated/delete-multiple1.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('34811c1b-85e5-4eb6-a5e3-d607b2f6986e', 'bucket2', 'authenticated/delete-multiple2.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('45950ff2-d3a8-4add-8e49-bafc01198340', 'bucket2', 'authenticated/delete-multiple3.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('469b0216-5419-41f6-9a37-2abfd7fad29c', 'bucket2', 'authenticated/delete-multiple4.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('55930619-a668-4dbc-aea3-b93dfe101e7f', 'bucket2', 'authenticated/delete-multiple7.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('D1CE4E4F-03E2-473D-858B-301D7989B581', 'bucket2', 'authenticated/rename-orig.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('222b3d1e-bc17-414c-b336-47894aa4d697', 'bucket2', 'authenticated/rename-orig-2.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('8f7d643d-1e82-4d39-ae39-d9bd6b0cfe9c', 'bucket2', 'authenticated/rename-orig-3.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-02-22 22:29:15.14732+00', '2021-02-22 22:29:15.14732+00', '2021-03-02 09:32:17.116+00', '{"mimetype": "image/png"}'), +('8377527d-3518-4dc8-8290-c6926470e795', 'bucket2', 'folder/subfolder/public-all-permissions.png', 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2', '2021-02-17 10:26:42.791214+00', '2021-02-17 11:03:30.025116+00', '2021-02-17 10:26:42.791214+00', NULL), +('b39ae4ab-802b-4c42-9271-3f908c34363c', 'bucket2', 'private/sadcat-upload3.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '{"mimetype": "image/svg+xml"}'), +('8098E1AC-C744-4368-86DF-71B60CCDE221', 'bucket3', 'sadcat-upload3.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '{"mimetype": "image/svg+xml"}'), +('D3EB488E-94F4-46CD-86D3-242C13B95BAC', 'bucket3', 'sadcat-upload2.png', '317eadce-631a-4429-a0bb-f19a7a517b4a', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '2021-03-01 08:53:29.567975+00', '{"mimetype": "image/svg+xml"}'); -- add policies -CREATE POLICY crud_public_folder ON objects for all USING (bucket_id='7078bc23-9dd6-460d-8b93-082254fee63a' and (foldername(name))[1] = 'public'); -CREATE POLICY crud_public_file ON objects for all USING (bucket_id='7078bc23-9dd6-460d-8b93-082254fee63a' and name = 'folder/subfolder/public-all-permissions.png'); -CREATE POLICY crud_uid_folder ON objects for all USING (bucket_id='7078bc23-9dd6-460d-8b93-082254fee63a' and (foldername(name))[1] = 'only_uid' and auth.uid() = 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2'); -CREATE POLICY crud_uid_file ON objects for all USING (bucket_id='7078bc23-9dd6-460d-8b93-082254fee63a' and name = 'folder/only_uid.jpg' and auth.uid() = 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2'); -CREATE POLICY authenticated_folder ON objects for all USING (bucket_id='7078bc23-9dd6-460d-8b93-082254fee63a' and (foldername(name))[1] = 'authenticated' and auth.role() = 'authenticated'); -CREATE POLICY crud_owner_only ON objects for all USING (bucket_id='7078bc23-9dd6-460d-8b93-082254fee63a' and (foldername(name))[1] = 'only_owner' and owner = auth.uid()); -CREATE POLICY delete_owner_only ON objects for all USING (bucket_id='7078bc23-9dd6-460d-8b93-082254fee63a' and (foldername(name))[1] = 'only_owner' and owner = auth.uid()); -CREATE POLICY open_all_update ON objects for all WITH CHECK (bucket_id='e29843e6-047e-4b1f-9906-20cc06f4aad4'); \ No newline at end of file +CREATE POLICY crud_public_folder ON objects for all USING (bucket_id='bucket2' and (foldername(name))[1] = 'public'); +CREATE POLICY crud_public_file ON objects for all USING (bucket_id='bucket2' and name = 'folder/subfolder/public-all-permissions.png'); +CREATE POLICY crud_uid_folder ON objects for all USING (bucket_id='bucket2' and (foldername(name))[1] = 'only_uid' and auth.uid() = 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2'); +CREATE POLICY crud_uid_file ON objects for all USING (bucket_id='bucket2' and name = 'folder/only_uid.jpg' and auth.uid() = 'd8c7bce9-cfeb-497b-bd61-e66ce2cbdaa2'); +CREATE POLICY authenticated_folder ON objects for all USING (bucket_id='bucket2' and (foldername(name))[1] = 'authenticated' and auth.role() = 'authenticated'); +CREATE POLICY crud_owner_only ON objects for all USING (bucket_id='bucket2' and (foldername(name))[1] = 'only_owner' and owner = auth.uid()); +CREATE POLICY delete_owner_only ON objects for all USING (bucket_id='bucket2' and (foldername(name))[1] = 'only_owner' and owner = auth.uid()); +CREATE POLICY open_all_update ON objects for all WITH CHECK (bucket_id='bucket4'); \ No newline at end of file