DASSL / ClassDB

An open-source system to let students experiment with relational data
https://dassl.github.io/ClassDB/
Other
8 stars 2 forks source link

Instructors with tables in the public schema cannot be dropped with dropInstructor (W) #107

Closed afig closed 7 years ago

afig commented 7 years ago

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.

>>SELECT classdb.dropInstructor('ins0');
ERROR:  role "ins0" cannot be dropped because some objects depend on it
DETAIL:  owner of table testinspub
CONTEXT:  SQL statement "DROP ROLE ins0"
PL/pgSQL function dropinstructor(character varying) line 15 at EXECUTE

We can force the role being dropped by adding a DROP OWNED BY in dropInstructor. 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.

s-aithal commented 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
smurthys commented 7 years ago
wildtayne commented 7 years ago
wildtayne commented 7 years ago

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.

wildtayne commented 7 years ago

I think the solution I outlined would be OK for M1. The superuser limitation is something we can document.

wildtayne commented 7 years ago

After our discussion, the solution we will implement for M1 is as follows: