Closed afig closed 7 years ago
Is this issue limited only to Instructors that have created a table in public schema? Alternatively, does executing createInstructor
function create any dependent object for an instructor that is not deleted when dropInstructor
is executed?
I executed createInstructor
and dropInstructor
without doing anything else in between the two commands. dropInstructor
gave the following error:
ERROR: role "ins2" cannot be dropped because some objects depend on it
DETAIL: owner of default privileges on new relations belonging to role ins2 in schema public
CONTEXT: SQL statement "DROP ROLE ins2"
PL/pgSQL function dropinstructor(character varying) line 15 at EXECUTE
dropXYZ
functions do what uninstall does to determine if a schema is to be dropped: test ownership by ClassDB
might be the only test missing.PUBLIC
are owned by the user themselves, they are left alone by the uninstaller. DROP OWNED BY
statement.ALTER DEFAULT PRIVILEGES
statement in classdb.creteInstructor
. The corresponding REVOKE
statement to undo this is missing from classdb.dropInstructor
.EXECUTE format(
'ALTER DEFAULT PRIVILEGES FOR ROLE %s IN SCHEMA PUBLIC REVOKE SELECT ON TABLES FROM PUBLIC;', $1);
If we want to go the reassign to current user route, we can use the line:
EXECUTE format('REASSIGN OWNED BY %s TO %I', $1, session_user);
after the instructor's schema is dropped, but before their role is. This will change the owner of all remaining objects the instructor owned to the user executing classdb.dropInstructor()
. Note session_user
is required here because classdb.dropInstructor()
is SECURITY DEFINER
.
There is one catch with this method however. This works fine if one instructor drops another, however, it will fail if a superuser executes it. This is because ClassDB
is the role actually executing classdb.dropInstructor()
. It has permission to assign objects to an instructor, but not a superuser.
I think the solution I outlined would be OK for M1. The superuser limitation is something we can document.
After our discussion, the solution we will implement for M1 is as follows:
listOrphans()
.removeFromDB()
is run, an exception will be thrown is listOrphans()
returns any rows, any the user will be informed that those objects must be reassigned or dropped.
If an Instructor has created a table in the public schema, then the role cannot be dropped with
dropInstructor
. This is because an object owned by the Instructor has not been dropped, which prevents Postgres from dropping the role. An example error message is displayed below.This does not affect other roles because they can only create objects within their own
$user
schema. Since the$user
schema is manually dropped before dropping any role, this does not end up being an issue for those roles.We can force the role being dropped by adding a
DROP OWNED BY
indropInstructor
. I am not 100% certain if this is something that we should do, since we could be dropping a relation that a user might not intend to be dropped. For now I am placing it into the backlog until we form a decision.