Skip to content

Commit

Permalink
Merge pull request #24 from GBSL-Informatik/fix/provide-shared-documents
Browse files Browse the repository at this point in the history
fix: provide shared documents
  • Loading branch information
lebalz authored Nov 18, 2024
2 parents 040c599 + 4eb1ab8 commit e9f3a11
Show file tree
Hide file tree
Showing 4 changed files with 441 additions and 0 deletions.
39 changes: 39 additions & 0 deletions prisma/dbml/schema.dbml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Table users {
rootUserPermissions root_user_permissions [not null]
studentGroups student_groups [not null]
view_DocumentUserPermissions view__document_user_permissions [not null]
view_AllDocumentUserPermissions view__all_document_user_permissions [not null]
}

Table student_groups {
Expand All @@ -28,6 +29,7 @@ Table student_groups {
children student_groups [not null]
users users [not null]
view_DocumentUserPermissions view__document_user_permissions [not null]
view_AllDocumentUserPermissions view__all_document_user_permissions [not null]
}

Table documents {
Expand All @@ -44,6 +46,7 @@ Table documents {
parent documents
children documents [not null]
view_DocumentUserPermissions view__document_user_permissions [not null]
view_AllDocumentUserPermissions view__all_document_user_permissions [not null]
}

Table document_roots {
Expand All @@ -54,6 +57,7 @@ Table document_roots {
rootGroupPermissions root_group_permissions [not null]
rootUserPermissions root_user_permissions [not null]
view_DocumentUserPermissions view__document_user_permissions [not null]
view_AllDocumentUserPermissions view__all_document_user_permissions [not null]
}

Table root_group_permissions {
Expand All @@ -64,6 +68,7 @@ Table root_group_permissions {
documentRoot document_roots [not null]
studentGroup student_groups [not null]
view_DocumentUserPermissions view__document_user_permissions [not null]
view_AllDocumentUserPermissions view__all_document_user_permissions [not null]
}

Table root_user_permissions {
Expand All @@ -74,6 +79,7 @@ Table root_user_permissions {
documentRoot document_roots [not null]
user users [not null]
view_DocumentUserPermissions view__document_user_permissions [not null]
view_AllDocumentUserPermissions view__all_document_user_permissions [not null]
}

Table sessions {
Expand All @@ -82,6 +88,27 @@ Table sessions {
expire DateTime [not null]
}

Table view__all_document_user_permissions {
documentRootId String [not null]
userId String [not null]
access Access [not null]
documentId String [not null]
rootUserPermissionId String
rootGroupPermissionId String
groupId String
accessRank Int [not null]
documentRoot document_roots [not null]
user users [not null]
document documents [not null]
rootUserPermission root_user_permissions
rootGroupPermission root_group_permissions
group student_groups

indexes {
(documentRootId, userId, documentId, accessRank) [unique]
}
}

Table view__document_user_permissions {
documentRootId String [not null]
userId String [not null]
Expand Down Expand Up @@ -154,6 +181,18 @@ Ref: root_user_permissions.documentRootId > document_roots.id [delete: Cascade]

Ref: root_user_permissions.userId > users.id [delete: Cascade]

Ref: view__all_document_user_permissions.documentRootId > document_roots.id

Ref: view__all_document_user_permissions.userId > users.id

Ref: view__all_document_user_permissions.documentId > documents.id

Ref: view__all_document_user_permissions.rootUserPermissionId > root_user_permissions.id

Ref: view__all_document_user_permissions.rootGroupPermissionId > root_group_permissions.id

Ref: view__all_document_user_permissions.groupId > student_groups.id

Ref: view__document_user_permissions.documentRootId > document_roots.id

Ref: view__document_user_permissions.userId > users.id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
-- assumption: all child documents of a document share the same document_root_id

CREATE OR REPLACE VIEW view__document_user_permissions AS
SELECT DISTINCT
document_root_id,
user_id,
access,
document_id,
root_user_permission_id,
root_group_permission_id,
group_id
FROM (
-- get all documents where the user **is the author**
-- including all child documents
WITH RECURSIVE
document_hierarchy AS (
-- Anchor member: select the root document
SELECT
document_roots.id AS document_root_id,
documents.id AS document_id,
documents.author_id AS user_id,
document_roots.access AS access,
NULL::uuid AS root_user_permission_id,
NULL::uuid AS root_group_permission_id,
NULL::uuid AS group_id
FROM
document_roots
INNER JOIN documents ON document_roots.id = documents.document_root_id
WHERE documents.parent_id IS NULL -- Assuming root documents have parent_id as NULL

UNION ALL -- keeps duplicates in the result set

-- Recursive member: select child documents with the parent's author as the user
SELECT
document_hierarchy.document_root_id AS document_root_id,
child_documents.id AS document_id,
document_hierarchy.user_id AS user_id,
document_hierarchy.access AS access,
NULL::uuid AS root_user_permission_id,
NULL::uuid AS root_group_permission_id,
NULL::uuid AS group_id
FROM
document_hierarchy
INNER JOIN documents AS child_documents ON document_hierarchy.document_id = child_documents.parent_id
),
-- get all documents where the user is **not the author**
-- but has been granted **shared access**
shared_doc_hierarchy AS (
-- Anchor member: select the root document
SELECT
document_roots.id AS document_root_id,
documents.id AS document_id,
all_users.id AS user_id,
document_roots.shared_access AS access,
NULL::uuid AS root_user_permission_id,
NULL::uuid AS root_group_permission_id,
NULL::uuid AS group_id
FROM
document_roots
INNER JOIN documents ON document_roots.id = documents.document_root_id
CROSS JOIN users all_users
WHERE documents.parent_id IS NULL -- Assuming root documents have parent_id as NULL
AND documents.author_id != all_users.id
AND (
document_roots.shared_access='RO_DocumentRoot'
OR
document_roots.shared_access='RW_DocumentRoot'
)

UNION ALL -- keeps duplicates in the result set

-- Recursive member: select child documents with the parent's author as the user
SELECT
shared_doc_hierarchy.document_root_id AS document_root_id,
child_documents.id AS document_id,
shared_doc_hierarchy.user_id AS user_id,
shared_doc_hierarchy.access AS access,
NULL::uuid AS root_user_permission_id,
NULL::uuid AS root_group_permission_id,
NULL::uuid AS group_id
FROM
shared_doc_hierarchy
INNER JOIN documents AS child_documents ON shared_doc_hierarchy.document_id = child_documents.parent_id
)
SELECT
document_root_id,
user_id,
access,
document_id,
root_user_permission_id,
root_group_permission_id,
group_id
FROM document_hierarchy
UNION
SELECT
document_root_id,
user_id,
access,
document_id,
root_user_permission_id,
root_group_permission_id,
group_id
FROM shared_doc_hierarchy
UNION
-- get all documents where the user has been granted shared access
-- or the access has been extended by user permissions
SELECT
document_roots.id AS document_root_id,
rup.user_id AS user_id,
rup.access AS access,
documents.id AS document_id,
rup.id AS root_user_permission_id,
NULL::uuid AS root_group_permission_id,
NULL::uuid AS group_id
FROM
document_roots
LEFT JOIN documents ON document_roots.id=documents.document_root_id
LEFT JOIN root_user_permissions rup
ON (
document_roots.id = rup.document_root_id
AND (
documents.author_id = rup.user_id
OR
rup.access >= document_roots.shared_access
)
)
WHERE rup.user_id IS NOT NULL
UNION
-- all group-based permissions for the documents author
SELECT
document_roots.id AS document_root_id,
sg_to_user."B" AS user_id,
rgp.access AS access,
documents.id AS document_id,
NULL::uuid AS root_user_permission_id,
rgp.id AS root_group_permission_id,
sg.id AS group_id
FROM
document_roots
INNER JOIN root_group_permissions rgp ON document_roots.id=rgp.document_root_id
INNER JOIN student_groups sg ON rgp.student_group_id=sg.id
LEFT JOIN documents ON document_roots.id=documents.document_root_id
LEFT JOIN "_StudentGroupToUser" sg_to_user
ON (
sg_to_user."A"=sg.id
AND (
sg_to_user."B"=documents.author_id
OR documents.author_id is null
)
)
WHERE sg_to_user."B" IS NOT NULL
UNION
-- all group based permissions for the user, which is not the author
SELECT
document_roots.id AS document_root_id,
sg_to_user."B" AS user_id,
rgp.access AS access,
documents.id AS document_id,
NULL::uuid AS root_user_permission_id,
rgp.id AS root_group_permission_id,
sg.id AS group_id
FROM
document_roots
INNER JOIN root_group_permissions rgp
ON (
document_roots.id=rgp.document_root_id
AND rgp.access >= document_roots.shared_access
)
INNER JOIN student_groups sg ON rgp.student_group_id=sg.id
LEFT JOIN documents ON document_roots.id=documents.document_root_id
LEFT JOIN "_StudentGroupToUser" sg_to_user
ON (
sg_to_user."A"=sg.id
AND sg_to_user."B"!=documents.author_id
)
WHERE sg_to_user."B" IS NOT NULL
) as doc_user_permissions;
Loading

0 comments on commit e9f3a11

Please sign in to comment.