The following query will return the id associated with a given document, a human readable list of permissions that are associated with a document, a string containing id’s of groups, roles, and users who have that permission assigned to them in a document (I’m aware that this method of assigning permissions is garbage, alas it’s what I was handed), and whether or not everyone has access via a REGEXP check. 1 = yes, everyone should have access to that permission on this document, 0 = not everyone.
SELECT
`D`.`id` AS `docID`,
`P`.`human_name` AS `permissionName`,
`PD`.`descriptor_text` AS `permissionAssignments`,
`PD`.`descriptor_text` REGEXP '.*role\\((-4,)?-3.*' AS `everyoneAccess`
FROM `documents` AS `D`
INNER JOIN `permission_lookups` AS `PL` ON `D`.`permission_lookup_id` = `PL`.`id`
INNER JOIN `permission_lookup_assignments` AS `PLA` ON `PL`.`id` = `PLA`.`permission_lookup_id`
INNER JOIN `permission_descriptors` AS `PD` ON `PLA`.`permission_descriptor_id` = `PD`.`id`
LEFT JOIN `permission_descriptor_roles` AS `PDR` ON `PDR`.`descriptor_id` = `PD`.`id`
LEFT JOIN `permissions` AS `P` ON `PLA`.`permission_id` = `P`.`id`
WHERE `D`.`id` = 74;
The output on this specific query looks similar to:
74 Read group(1)role(-3)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294,15389) 1
74 Write group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294) 0
74 Add Folder group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294) 0
74 Manage security group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294) 0
74 Delete group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294) 0
74 Manage workflow group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294) 0
74 Folder Details group(1)role(-3)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294,15389) 1
74 Rename Folder group(1) 0
Under the 3rd column, first row (for example), the string: group(1)role(-3)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294,15389) means that the group with id 1 has access to the read permission, the role with id -3 has access (-3 means everyone) to the read permission, and with different role allocations and such, at a resolved state, users with the ids 13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294,15389 have access. So in this instance, everyone has access due to the document having the everyone role assigned to it, but they also gave specific access to the long string of users as a blanket across all permissions.
What I want to do, is pull out the csv list of users, and use that in a subquery to pull out their usernames in the same query. I try the following query but without any luck, it only returns the first user in the csv list:
SELECT
`D`.`id` AS `docID`,
`P`.`human_name` AS `permissionName`,
`PD`.`descriptor_text` AS `permissionAssignments`,
`PD`.`descriptor_text` REGEXP '.*role\\((-4,)?-3.*' AS `everyoneAccess`,
IF(`PD`.`descriptor_text` REGEXP '.*user\\([0-9,]+)$',
(SELECT group_concat(`username`) FROM users where `id` IN
(
SUBSTR(
`PD`.`descriptor_text`,
INSTR(`PD`.`descriptor_text`, 'user(') + 5,
LENGTH(`PD`.`descriptor_text`) - INSTR(`PD`.`descriptor_text`, 'user(') - 5
)
)
),
NULL
)
FROM `documents` AS `D`
INNER JOIN `permission_lookups` AS `PL` ON `D`.`permission_lookup_id` = `PL`.`id`
INNER JOIN `permission_lookup_assignments` AS `PLA` ON `PL`.`id` = `PLA`.`permission_lookup_id`
INNER JOIN `permission_descriptors` AS `PD` ON `PLA`.`permission_descriptor_id` = `PD`.`id`
LEFT JOIN `permission_descriptor_roles` AS `PDR` ON `PDR`.`descriptor_id` = `PD`.`id`
LEFT JOIN `permissions` AS `P` ON `PLA`.`permission_id` = `P`.`id`
WHERE `D`.`id` = 74;
What can be changed in that 4th field to have it query for a group_concat list of the usernames based off the csv of id’s?
Can’t promise this will be fast, but I believe it solves your problem.
Instead of trying to break up the string, you search for the id in the string with a carefully constructed regex.