immich/server/test/repositories
Michael Manganiello c04340c63e
chore(server): Check more permissions in bulk (#5315)
Modify Access repository, to evaluate `authDevice`, `library`, `partner`,
`person`, and `timeline` permissions in bulk.
Queries have been validated to match what they currently generate for
single ids.

As an extra performance improvement, we now use a custom QueryBuilder
for the Partners queries, to avoid the eager relationships that add
unneeded `LEFT JOIN` clauses. We only filter based on the ids present in
the `partners` table, so those joins can be avoided.

Queries:

* `library` owner access:

```sql
-- Before
SELECT 1 AS "row_exists" FROM (SELECT 1 AS dummy_column) "dummy_table" WHERE EXISTS (
  SELECT 1
  FROM "libraries" "LibraryEntity"
  WHERE
    "LibraryEntity"."id" = $1
    AND "LibraryEntity"."ownerId" = $2
    AND "LibraryEntity"."deletedAt" IS NULL
)
LIMIT 1

-- After
SELECT "LibraryEntity"."id" AS "LibraryEntity_id"
FROM "libraries" "LibraryEntity"
WHERE
  "LibraryEntity"."id" IN ($1, $2)
  AND "LibraryEntity"."ownerId" = $3
  AND "LibraryEntity"."deletedAt" IS NULL
```

* `library` partner access:

```sql
-- Before
SELECT 1 AS "row_exists" FROM (SELECT 1 AS dummy_column) "dummy_table" WHERE EXISTS (
  SELECT 1
  FROM "partners" "PartnerEntity"
    LEFT JOIN "users" "PartnerEntity__sharedBy"
      ON "PartnerEntity__sharedBy"."id"="PartnerEntity"."sharedById"
      AND "PartnerEntity__sharedBy"."deletedAt" IS NULL
    LEFT JOIN "users" "PartnerEntity__sharedWith"
      ON "PartnerEntity__sharedWith"."id"="PartnerEntity"."sharedWithId"
      AND "PartnerEntity__sharedWith"."deletedAt" IS NULL
  WHERE
    "PartnerEntity"."sharedWithId" = $1
    AND "PartnerEntity"."sharedById" = $2
)
LIMIT 1

-- After
SELECT
  "partner"."sharedById" AS "partner_sharedById",
  "partner"."sharedWithId" AS "partner_sharedWithId"
FROM "partners" "partner"
WHERE
  "partner"."sharedById" IN ($1, $2)
  AND "partner"."sharedWithId" = $3
```

* `authDevice` owner access:

```sql
-- Before
SELECT 1 AS "row_exists" FROM (SELECT 1 AS dummy_column) "dummy_table" WHERE EXISTS (
  SELECT 1
  FROM "user_token" "UserTokenEntity"
  WHERE
    "UserTokenEntity"."userId" = $1
    AND "UserTokenEntity"."id" = $2
)
LIMIT 1

-- After
SELECT "UserTokenEntity"."id" AS "UserTokenEntity_id"
FROM "user_token" "UserTokenEntity"
WHERE
  "UserTokenEntity"."userId" = $1
  AND "UserTokenEntity"."id" IN ($2, $3)
```

* `timeline` partner access:

```sql
-- Before
SELECT 1 AS "row_exists" FROM (SELECT 1 AS dummy_column) "dummy_table" WHERE EXISTS (
  SELECT 1
  FROM "partners" "PartnerEntity"
    LEFT JOIN "users" "PartnerEntity__sharedBy"
      ON "PartnerEntity__sharedBy"."id"="PartnerEntity"."sharedById"
      AND "PartnerEntity__sharedBy"."deletedAt" IS NULL
    LEFT JOIN "users" "PartnerEntity__sharedWith"
      ON "PartnerEntity__sharedWith"."id"="PartnerEntity"."sharedWithId"
      AND "PartnerEntity__sharedWith"."deletedAt" IS NULL
  WHERE
    "PartnerEntity"."sharedWithId" = $1
    AND "PartnerEntity"."sharedById" = $2
)
LIMIT 1

-- After
SELECT
  "partner"."sharedById" AS "partner_sharedById",
  "partner"."sharedWithId" AS "partner_sharedWithId"
FROM "partners" "partner"
WHERE
  "partner"."sharedById" IN ($1, $2)
  AND "partner"."sharedWithId" = $3
```

* `person` owner access:

```sql
-- Before
SELECT 1 AS "row_exists" FROM (SELECT 1 AS dummy_column) "dummy_table" WHERE EXISTS (
  SELECT 1
  FROM "person" "PersonEntity"
  WHERE
    "PersonEntity"."id" = $1
    AND "PersonEntity"."ownerId" = $2
)
LIMIT 1

-- After
SELECT "PersonEntity"."id" AS "PersonEntity_id"
FROM "person" "PersonEntity"
WHERE
  "PersonEntity"."id" IN ($1, $2)
  AND "PersonEntity"."ownerId" = $3
```

* `partner` update access:

```sql
-- Before
SELECT 1 AS "row_exists" FROM (SELECT 1 AS dummy_column) "dummy_table" WHERE EXISTS (
  SELECT 1
  FROM "partners" "PartnerEntity"
    LEFT JOIN "users" "PartnerEntity__sharedBy"
      ON "PartnerEntity__sharedBy"."id"="PartnerEntity"."sharedById"
      AND "PartnerEntity__sharedBy"."deletedAt" IS NULL
    LEFT JOIN "users" "PartnerEntity__sharedWith"
      ON "PartnerEntity__sharedWith"."id"="PartnerEntity"."sharedWithId"
      AND "PartnerEntity__sharedWith"."deletedAt" IS NULL
  WHERE
    "PartnerEntity"."sharedWithId" = $1
    AND "PartnerEntity"."sharedById" = $2
)
LIMIT 1

-- After
SELECT
  "partner"."sharedById" AS "partner_sharedById",
  "partner"."sharedWithId" AS "partner_sharedWithId"
FROM "partners" "partner"
WHERE
  "partner"."sharedById" IN ($1, $2)
  AND "partner"."sharedWithId" = $3
```
2023-11-26 07:50:41 -05:00
..
access.repository.mock.ts chore(server): Check more permissions in bulk (#5315) 2023-11-26 07:50:41 -05:00
activity.repository.mock.ts feat(web,server): activity (#4682) 2023-10-31 22:13:34 -05:00
album.repository.mock.ts fix(server): album perf query (#5232) 2023-11-21 10:07:49 -06:00
api-key.repository.mock.ts refactor(server)*: tsconfigs (#2689) 2023-06-08 10:01:07 -05:00
asset.repository.mock.ts refactor: deprecate getUserAssetsByDeviceId (#5273) 2023-11-25 15:46:20 +00:00
audit.repository.mock.ts feat(server): asset entity audit (#3824) 2023-08-24 15:28:50 -04:00
communication.repository.mock.ts refactor(server, web)!: store latest immich version available on the server (#3565) 2023-10-24 11:05:42 -04:00
crypto.repository.mock.ts refactor(server): android motion photos (#3711) 2023-09-13 10:46:37 +07:00
index.ts refactor(server, web)!: store latest immich version available on the server (#3565) 2023-10-24 11:05:42 -04:00
job.repository.mock.ts feat(server): custom library scanning interval (#4390) 2023-10-31 15:19:12 -05:00
library.repository.mock.ts feat(server,web): libraries (#3124) 2023-09-20 13:16:33 +02:00
machine-learning.repository.mock.ts refactor(server)*: tsconfigs (#2689) 2023-06-08 10:01:07 -05:00
media.repository.mock.ts feat(server): tone-mapping (#3512) 2023-08-07 15:35:25 -05:00
metadata.repository.mock.ts feat: postgres reverse geocoding (#5301) 2023-11-25 18:53:30 +00:00
move.repository.mock.ts feat(server): harden move file (#4361) 2023-10-10 21:14:44 -05:00
partner.repository.mock.ts feat(web): show partners assets on the main timeline (#4933) 2023-11-11 21:06:19 +00:00
person.repository.mock.ts fix: suggest people (#4566) 2023-10-24 15:53:49 +00:00
search.repository.mock.ts feat(ml)!: customizable ML settings (#3891) 2023-08-29 08:58:00 -05:00
shared-link.repository.mock.ts refactor(server)*: tsconfigs (#2689) 2023-06-08 10:01:07 -05:00
smart-info.repository.mock.ts refactor(server)*: tsconfigs (#2689) 2023-06-08 10:01:07 -05:00
storage.repository.mock.ts refactor(server): make storage core singleton (#4608) 2023-10-23 11:52:21 -04:00
system-config.repository.mock.ts feat: Maplibre (#4294) 2023-11-09 10:10:56 -06:00
system-info.repository.mock.ts refactor(server, web)!: store latest immich version available on the server (#3565) 2023-10-24 11:05:42 -04:00
tag.repository.mock.ts refactor(server)*: tsconfigs (#2689) 2023-06-08 10:01:07 -05:00
user-token.repository.mock.ts refactor(server)*: tsconfigs (#2689) 2023-06-08 10:01:07 -05:00
user.repository.mock.ts refactor(server): make user core singleton (#4607) 2023-10-23 08:38:48 -04:00