diff options
Diffstat (limited to 'migrations/auth')
11 files changed, 443 insertions, 0 deletions
diff --git a/migrations/auth/20250328_01_72EFk-add-admin-ui-privilege-to-system-administrator-role.py b/migrations/auth/20250328_01_72EFk-add-admin-ui-privilege-to-system-administrator-role.py new file mode 100644 index 0000000..d22ad01 --- /dev/null +++ b/migrations/auth/20250328_01_72EFk-add-admin-ui-privilege-to-system-administrator-role.py @@ -0,0 +1,42 @@ +""" +add admin ui privilege to system-administrator role +""" +import contextlib + +from yoyo import step + +__depends__ = {'20240924_01_thbvh-hooks-for-edu-domains'} + +def get_system_admin_id(cursor): + cursor.execute( + "SELECT role_id FROM roles WHERE role_name='system-administrator'") + return cursor.fetchone()[0] + +def add_admin_ui_privilege(conn): + with contextlib.closing(conn.cursor()) as cursor: + # Create admin-ui privilege + cursor.execute( + "INSERT INTO privileges (privilege_id, privilege_description) " + "VALUES(?, ?)", + ("system:user:admin-ui", "View UI elements that should only be visible to system administrators")) + + # Add UI privilege to system-administrator role + cursor.execute( + "INSERT INTO role_privileges (role_id, privilege_id) " + "VALUES(?, ?)", + (get_system_admin_id(cursor), "system:user:admin-ui") + ) + +def remove_admin_ui_privilege(conn): + with contextlib.closing(conn.cursor()) as cursor: + # Remove UI privilege from system-administrator role + cursor.execute( + "DELETE FROM role_privileges WHERE privilege_id='system:user:admin-ui'") + + # Remove UI privilege from privileges table + cursor.execute( + "DELETE FROM privileges WHERE privilege_id='system:user:admin-ui'") + +steps = [ + step(add_admin_ui_privilege, remove_admin_ui_privilege) +] diff --git a/migrations/auth/20250609_01_LB60X-add-batch-edit-privileges.py b/migrations/auth/20250609_01_LB60X-add-batch-edit-privileges.py new file mode 100644 index 0000000..73a4880 --- /dev/null +++ b/migrations/auth/20250609_01_LB60X-add-batch-edit-privileges.py @@ -0,0 +1,49 @@ +""" +Add Batch Edit privileges +""" + +import contextlib + +from yoyo import step + +__depends__ = {'20250328_01_72EFk-add-admin-ui-privilege-to-system-administrator-role'} + +def add_batch_edit_privilege_and_role(conn): + with contextlib.closing(conn.cursor()) as cursor: + # Create batch edit privilege + cursor.execute( + "INSERT INTO privileges (privilege_id, privilege_description) " + "VALUES(?, ?)", + ("system:data:batch-edit", "Batch Edit")) + + # Create batch editor role + cursor.execute( + "INSERT INTO roles (role_id, role_name, user_editable) " + "VALUES(?, ?, ?)", + ("0f391910-5225-476a-bb8d-9c0adc9d81cc", "Batch Editors", 0)) + + # Link role/privilege + cursor.execute( + "INSERT INTO role_privileges (role_id, privilege_id) " + "VALUES(?, ?)", + ("0f391910-5225-476a-bb8d-9c0adc9d81cc", "system:data:batch-edit") + ) + +def remove_batch_edit_privilege_and_role(conn): + with contextlib.closing(conn.cursor()) as cursor: + # Remove batch edit role/privilege link + cursor.execute( + "DELETE FROM role_privileges WHERE privilege_id='system:data:batch-edit'") + + # Remove Batch Editor role + cursor.execute( + "DELETE FROM roles WHERE role_id='0f391910-5225-476a-bb8d-9c0adc9d81cc'") + + # Remove Batch Edit privilege + cursor.execute( + "DELETE FROM privileges WHERE privilege_id='system:data:batch-edit'") + + +steps = [ + step(add_batch_edit_privilege_and_role, remove_batch_edit_privilege_and_role) +] diff --git a/migrations/auth/20250609_01_bj9Pl-add-new-group-data-link-to-group-privilege.py b/migrations/auth/20250609_01_bj9Pl-add-new-group-data-link-to-group-privilege.py new file mode 100644 index 0000000..3b9e928 --- /dev/null +++ b/migrations/auth/20250609_01_bj9Pl-add-new-group-data-link-to-group-privilege.py @@ -0,0 +1,19 @@ +""" +Add new 'group:data:link-to-group' privilege. +""" + +from yoyo import step + +__depends__ = {'20240924_01_thbvh-hooks-for-edu-domains'} + +steps = [ + step( + """ + INSERT INTO privileges(privilege_id, privilege_description) + VALUES( + 'group:data:link-to-group', + 'Allow linking data to only one specific group.' + ) + """, + "DELETE FROM privileges WHERE privilege_id='group:data:link-to-group'") +] diff --git a/migrations/auth/20250609_02_9UBPl-assign-group-data-link-to-group-privilege-to-group-leader.py b/migrations/auth/20250609_02_9UBPl-assign-group-data-link-to-group-privilege-to-group-leader.py new file mode 100644 index 0000000..5d9c306 --- /dev/null +++ b/migrations/auth/20250609_02_9UBPl-assign-group-data-link-to-group-privilege-to-group-leader.py @@ -0,0 +1,23 @@ +""" +Assign 'group:data:link-to-group' privilege to group leader. +""" + +from yoyo import step + +__depends__ = {'20250609_01_bj9Pl-add-new-group-data-link-to-group-privilege'} + +steps = [ + step( + """ + INSERT INTO role_privileges(role_id, privilege_id) + VALUES( + 'a0e67630-d502-4b9f-b23f-6805d0f30e30', + 'group:data:link-to-group' + ) + """, + """ + DELETE FROM role_privileges + WHERE role_id='a0e67630-d502-4b9f-b23f-6805d0f30e30' + AND privilege_id='group:data:link-to-group' + """) +] diff --git a/migrations/auth/20250703_01_aDVwP-add-role-management-privileges-to-group-leader-role.py b/migrations/auth/20250703_01_aDVwP-add-role-management-privileges-to-group-leader-role.py new file mode 100644 index 0000000..6335152 --- /dev/null +++ b/migrations/auth/20250703_01_aDVwP-add-role-management-privileges-to-group-leader-role.py @@ -0,0 +1,27 @@ +""" +Add role management privileges to group-leader role +""" + +from yoyo import step + +__depends__ = {'20250609_01_LB60X-add-batch-edit-privileges', '20250609_02_9UBPl-assign-group-data-link-to-group-privilege-to-group-leader'} + +steps = [ + step( + """ + INSERT INTO role_privileges(role_id, privilege_id) + VALUES + ('a0e67630-d502-4b9f-b23f-6805d0f30e30', 'resource:role:create-role'), + ('a0e67630-d502-4b9f-b23f-6805d0f30e30', 'resource:role:delete-role'), + ('a0e67630-d502-4b9f-b23f-6805d0f30e30', 'resource:role:edit-role') + """, + """ + DELETE FROM role_privileges + WHERE role_id='a0e67630-d502-4b9f-b23f-6805d0f30e30' + AND privilege_id IN ( + 'resource:role:create-role', + 'resource:role:delete-role', + 'resource:role:edit-role' + ) + """) +] diff --git a/migrations/auth/20250722_01_7Gro7-create-new-system-user-edit-privilege.py b/migrations/auth/20250722_01_7Gro7-create-new-system-user-edit-privilege.py new file mode 100644 index 0000000..f00ab11 --- /dev/null +++ b/migrations/auth/20250722_01_7Gro7-create-new-system-user-edit-privilege.py @@ -0,0 +1,18 @@ +""" +Create new 'system:user:edit' privilege. +""" + +from yoyo import step + +__depends__ = {'20250703_01_aDVwP-add-role-management-privileges-to-group-leader-role'} + +steps = [ + step( + """ + INSERT INTO privileges(privilege_id, privilege_description) + VALUES( + 'system:user:edit', + 'Allow general user-information edit.') + """, + "DELETE FROM privileges WHERE privilege_id='system:user:edit'") +] diff --git a/migrations/auth/20250722_02_M8TXv-add-system-user-edit-privilege-to-system-admin-role.py b/migrations/auth/20250722_02_M8TXv-add-system-user-edit-privilege-to-system-admin-role.py new file mode 100644 index 0000000..b956bef --- /dev/null +++ b/migrations/auth/20250722_02_M8TXv-add-system-user-edit-privilege-to-system-admin-role.py @@ -0,0 +1,36 @@ +""" +Add 'system:user:edit' privilege to 'system-admin' role. +""" +import contextlib + +from yoyo import step + +__depends__ = {'20250722_01_7Gro7-create-new-system-user-edit-privilege'} + + +def system_administrator_role_id(cursor): + """Fetch ID for role 'system-administrator'.""" + cursor.execute( + "SELECT role_id FROM roles WHERE role_name='system-administrator'") + return cursor.fetchone()[0] + + +def add_system_user_edit_privilege(conn): + """Add the 'system:user:edit' to the 'system-administrator' role.""" + with contextlib.closing(conn.cursor()) as cursor: + cursor.execute( + "INSERT INTO role_privileges(role_id, privilege_id) " + "VALUES(?, ?)", + (system_administrator_role_id(cursor), 'system:user:edit')) + + +def remove_system_user_edit_privilege(conn): + """Remove the 'system:user:edit' from the 'system-administrator' role.""" + with contextlib.closing(conn.cursor()) as cursor: + cursor.execute( + "DELETE FROM role_privileges WHERE role_id=? AND privilege_id=?", + (system_administrator_role_id(cursor), 'system:user:edit')) + +steps = [ + step(add_system_user_edit_privilege, remove_system_user_edit_privilege) +] diff --git a/migrations/auth/20250729_01_CNn2p-create-initial-system-wide-resources-access-privileges.py b/migrations/auth/20250729_01_CNn2p-create-initial-system-wide-resources-access-privileges.py new file mode 100644 index 0000000..be0d022 --- /dev/null +++ b/migrations/auth/20250729_01_CNn2p-create-initial-system-wide-resources-access-privileges.py @@ -0,0 +1,31 @@ +""" +Create initial system-wide resources access privileges +""" + +from yoyo import step + +__depends__ = {'20250722_02_M8TXv-add-system-user-edit-privilege-to-system-admin-role'} + +steps = [ + step( + """ + INSERT INTO privileges(privilege_id, privilege_description) + VALUES + ("system:resource:view", + "View the wrapper resource object (not attached data). This is mostly for administration purposes."), + ("system:resource:edit", + "Edit/update the wrapper resource object (not attached data). This is mostly for administration purposes."), + ("system:resource:delete", + "Delete the wrapper resource object (not attached data). This is mostly for administration purposes."), + ("system:resource:reassign-group", + "Reassign the resource, and its data, to a different user group."), + ("system:resource:assign-owner", + "Assign ownership of any resource to any user.") + """, + """ + DELETE FROM privileges WHERE privilege_id IN + ("system:resource:view", "system:resource:edit", + "system:resource:delete", "system:resource:reassign-group", + "system:resource:assign-owner") + """) +] diff --git a/migrations/auth/20250729_02_7ycSm-assign-initial-system-wide-resources-access-privileges-to-sys-admins.py b/migrations/auth/20250729_02_7ycSm-assign-initial-system-wide-resources-access-privileges-to-sys-admins.py new file mode 100644 index 0000000..e79ab1c --- /dev/null +++ b/migrations/auth/20250729_02_7ycSm-assign-initial-system-wide-resources-access-privileges-to-sys-admins.py @@ -0,0 +1,53 @@ +""" +Assign initial system-wide resources-access privileges to sys-admins. +""" +import contextlib + +from yoyo import step + +def system_administrator_role_id(cursor): + """Fetch ID for role 'system-administrator'.""" + cursor.execute( + "SELECT role_id FROM roles WHERE role_name='system-administrator'") + return cursor.fetchone()[0] + + +def assign_system_wide_resource_access_to_sysadmin(conn): + """ + Assign initial system-wide resources-access privileges to + `system-administrator` role. + """ + with contextlib.closing(conn.cursor()) as cursor: + sysadmin_role_id = system_administrator_role_id(cursor) + cursor.executemany( + "INSERT INTO role_privileges(role_id, privilege_id) " + "VALUES(?, ?)", + ((sysadmin_role_id, "system:resource:view"), + (sysadmin_role_id, "system:resource:edit"), + (sysadmin_role_id, "system:resource:delete"), + (sysadmin_role_id, "system:resource:reassign-group"), + (sysadmin_role_id, "system:resource:assign-owner"))) + + +def revoke_system_wide_resource_access_from_sysadmin(conn): + """ + Revoke initial system-wide resources-access privileges from + `system-administrator` role. + """ + with contextlib.closing(conn.cursor()) as cursor: + sysadmin_role_id = system_administrator_role_id(cursor) + cursor.executemany( + "DELETE FROM role_privileges " + "WHERE role_id=? AND privilege_id=?", + ((sysadmin_role_id, "system:resource:view"), + (sysadmin_role_id, "system:resource:edit"), + (sysadmin_role_id, "system:resource:delete"), + (sysadmin_role_id, "system:resource:reassign-group"), + (sysadmin_role_id, "system:resource:assign-owner"))) + +__depends__ = {'20250729_01_CNn2p-create-initial-system-wide-resources-access-privileges'} + +steps = [ + step(assign_system_wide_resource_access_to_sysadmin, + revoke_system_wide_resource_access_from_sysadmin) +] diff --git a/migrations/auth/20250729_03_oCvvq-grant-role-to-all-resources-to-sys-admin-users.py b/migrations/auth/20250729_03_oCvvq-grant-role-to-all-resources-to-sys-admin-users.py new file mode 100644 index 0000000..e3bdc8f --- /dev/null +++ b/migrations/auth/20250729_03_oCvvq-grant-role-to-all-resources-to-sys-admin-users.py @@ -0,0 +1,75 @@ +""" +Grant role to ALL resources to sys-admin users. +""" +import itertools +import contextlib + +from yoyo import step + +__depends__ = {'20250729_02_7ycSm-assign-initial-system-wide-resources-access-privileges-to-sys-admins'} + + +def system_administrator_role_id(cursor): + """Fetch ID for role 'system-administrator'.""" + cursor.execute( + "SELECT role_id FROM roles WHERE role_name='system-administrator'") + return cursor.fetchone()[0] + + +def system_resource_id(cursor): + cursor.execute( + "SELECT resources.resource_id FROM resource_categories " + "INNER JOIN resources ON resource_categories.resource_category_id=resources.resource_category_id " + "WHERE resource_category_key = 'system'") + return cursor.fetchone()[0] + + +def fetch_ids_for_sysadmin_users(cursor): + """Fetch all sysadmin users' IDs.""" + cursor.execute( + "SELECT user_roles.user_id FROM roles INNER JOIN user_roles " + "ON roles.role_id=user_roles.role_id " + "WHERE role_name='system-administrator' AND resource_id=?", + (system_resource_id(cursor),)) + return tuple(row[0] for row in cursor.fetchall()) + + +def fetch_non_system_resources(cursor): + """Fetch IDs for all resources that are not of the 'system' category.""" + cursor.execute( + "SELECT resources.resource_id FROM resource_categories " + "INNER JOIN resources " + "ON resource_categories.resource_category_id=resources.resource_category_id " + "WHERE resource_category_key != 'system'") + return tuple(row[0] for row in cursor.fetchall()) + + +def assign_sysadmin_role_on_non_system_resources(conn): + """Assign sysadmins the sysadmin role on all non-system resources.""" + with contextlib.closing(conn.cursor()) as cursor: + sysadminroleid = system_administrator_role_id(cursor) + cursor.executemany( + "INSERT INTO user_roles(user_id, resource_id, role_id) " + "VALUES (?, ?, ?)", + tuple(item + (sysadminroleid,) + for item in itertools.product( + fetch_ids_for_sysadmin_users(cursor), + fetch_non_system_resources(cursor)))) + + +def revoke_sysadmin_role_on_non_system_resources(conn): + """Revoke sysadmins the sysadmin role on all non-system resources.""" + with contextlib.closing(conn.cursor()) as cursor: + sysadminroleid = system_administrator_role_id(cursor) + cursor.executemany( + "DELETE FROM user_roles " + "WHERE user_id=? AND resource_id=? AND role_id=?", + tuple(item + (sysadminroleid,) + for item in itertools.product( + fetch_ids_for_sysadmin_users(cursor), + fetch_non_system_resources(cursor)))) + +steps = [ + step(assign_sysadmin_role_on_non_system_resources, + revoke_sysadmin_role_on_non_system_resources) +] diff --git a/migrations/auth/20250731_01_Ke1us-add-sysadmin-privileges-for-acting-on-groups-members.py b/migrations/auth/20250731_01_Ke1us-add-sysadmin-privileges-for-acting-on-groups-members.py new file mode 100644 index 0000000..95a6fbb --- /dev/null +++ b/migrations/auth/20250731_01_Ke1us-add-sysadmin-privileges-for-acting-on-groups-members.py @@ -0,0 +1,70 @@ +""" +Add sysadmin privileges for acting on groups: mostly handling user management. +""" +import itertools +import contextlib + +from yoyo import step + +__depends__ = {'20250729_03_oCvvq-grant-role-to-all-resources-to-sys-admin-users'} + + +def system_administrator_role_id(cursor): + """Fetch ID for role 'system-administrator'.""" + cursor.execute( + "SELECT role_id FROM roles WHERE role_name='system-administrator'") + return cursor.fetchone()[0] + + +def add_group_privileges_to_sysadmin_role(conn): + """Add group-management privileges to sysadmin role.""" + with contextlib.closing(conn.cursor()) as cursor: + sysadminroleid = system_administrator_role_id(cursor) + cursor.executemany( + "INSERT INTO role_privileges(role_id, privilege_id) VALUES (?, ?)", + tuple(itertools.product( + (sysadminroleid,), + ('system:group:add-group-member', + 'system:group:remove-group-member', + 'system:group:assign-group-leader', + 'system:group:revoke-group-leader')))) + + +def remove_group_privileges_to_sysadmin_role(conn): + """Remove group-management privileges from sysadmin role.""" + with contextlib.closing(conn.cursor()) as cursor: + sysadminroleid = system_administrator_role_id(cursor) + cursor.executemany( + "DELETE FROM role_privileges WHERE role_id=? AND privilege_id=?", + tuple(itertools.product( + (sysadminroleid,), + ('system:group:add-group-member', + 'system:group:remove-group-member', + 'system:group:assign-group-leader', + 'system:group:revoke-group-leader')))) + + +steps = [ + step( + """ + INSERT INTO privileges(privilege_id, privilege_description) + VALUES + ('system:group:add-group-member', + 'Make an existing user a member of a group.'), + ('system:group:remove-group-member', + 'Remove a member user from a group.'), + ('system:group:assign-group-leader', + 'Assign an existing group member the group-leader role'), + ('system:group:revoke-group-leader', + 'Revoke the group-leader role from a group member with the role.') + """, + """ + DELETE FROM privileges WHERE privilege_id IN + ('system:group:add-group-member', + 'system:group:remove-group-member', + 'system:group:assign-group-leader', + 'system:group:revoke-group-leader') + """), + step(add_group_privileges_to_sysadmin_role, + remove_group_privileges_to_sysadmin_role) +] |
