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

RoleBase compatable ClassDB GroupRole functions and views #155

Closed afig closed 6 years ago

afig commented 6 years ago

This Pull Request provides an implementation of the GroupRole-specific functions and views defined for M2.

This includes the Instructor, Student, and DBManager views, and the following functions defined for each group:

addClassDBRolesMgmt.sql:

addHelpers.sql:

The Git diff for addClassDBRolesMgmt.sql is not very useful, since practically all code in that file was replaced. It will likely be easier to compare the files separately (i.e. without highlighting).

The implementation for the three views is currently commented out as the User view they are based off of is not yet implemented

Incomplete, nominal tests have been created for createStudent() only. I will continue to redevelop the tests for the remaining functions.

Some tests exist for the new isXYZ functions, but they are not pushed yet since there is some odd behavior from pg_has_role that needs to be investigated.

wildtayne commented 6 years ago

Looks good so far. One observation I had:

addHelpers.sql

smurthys commented 6 years ago

Quick comments:

wildtayne commented 6 years ago

Related to this comment, I think ClassDB.Student and the like are missing the LastDDLOperation column.

Also, I get an error when calling dropStudent:

QUERY:  ALTER ROLE ddlStudent01 CONNECTION LIMIT TO -1
CONTEXT:  PL/pgSQL function revokestudent(idnamedomain) line 9 at EXECUTE
SQL statement "SELECT ClassDB.revokeStudent($1)"
PL/pgSQL function dropstudent(idnamedomain,boolean,boolean,character varying,idnamedomain) line 4 at PERFORM
SQL statement "SELECT ClassDB.dropStudent('ddlStudent01', true)"
PL/pgSQL function inline_code_block line 47 at PERFORM

I think in revokeStudent(), the statement should just be ALTER ROLE * CONNECTION LIMIT -1

afig commented 6 years ago

Thanks for the preliminary review @srrollo and @smurthys. I agree with all recommendations/observations made so far. I will implement those changes, add the remaining tests, and fix any other issues I observe in the process.

smurthys commented 6 years ago

I am reviewing the files, and have one quick comment:

I feel it is better to partially define Instructor and other views as is done with User view in addUserMgmt.sql. Then show branch add-UserMgmt as blocking this PR instead of branch add-user-view.

smurthys commented 6 years ago

Thanks @afig for the commits.

I have the following observations on addClassDBRolesMgmt.sql:

Unrelated to this PR, but there is a bug in addRoleBaseMgmt.sql that impacts createStudent etc. I have created Issue #158.

afig commented 6 years ago

Thanks for the more detailed review @smurthys.

Thinking about it, it would in fact be less confusing if the isXYZ functions only returned true for users that are "known". It would also be consistent with the 3 views that are defined nearby and in practice, likely used together with these functions. As far as their permissions go, the current implementation (not checking if the user is known) might as well be executed by anyone since as mentioned, the ClassDB.isMember() function and pg_catalog.pg_roles view are accessible by anyone. However, I agree that the proposed implementation of ensuring that a user is known warrants stricter execution privileges, such that only users with the ClassDB_Instructor or ClassDB_DBManager (or ClassDB) roles can execute them.

Granting SELECT on ALL TABLES in a schema does grant SELECT on views, but not EXECUTE on functions. To do the latter, we would also have to add a statement that grants EXECUTE on ALL FUNCTIONS. It makes sense to also include EXECUTE on functions. Of course, the docs will have to be updated to reflect this (and practically every other change introduced with this PR).

I agree that okIfRemainsClassDBRoleMember communicates something different from the okIfClassDBRoleMember parameter in dropRole. However, this is because it is expected that the user being dropped is currently a ClassDB Role Member, otherwise, there's no purpose in using the dropXYZ functions (we still have to plan for this situation, but it is not a nominal case). Since the parameter in question is not passed to dropRole until after a corresponding revoke is performed, it effectively serves as "remains" a classdb role once the current role is revoked. However, a comment is likely needed that explains this behavior.

smurthys commented 6 years ago

Quickly, in addClassDBRolesMgmt.sql: L273-L280 use incorrect function signature (uses previous version) causing compilation error.

wildtayne commented 6 years ago

I think this looks pretty much good to go. Also, all of the functionality I have used works well. Similarly to this, should ClassDB.Instructor/Student/DBManager be removed prior to merging?

smurthys commented 6 years ago

Yes, the Instructor etc. views should be removed from addClassDBRolesMgmt.sql due to PR #159

smurthys commented 6 years ago

I have the following observations about addClassDBRolesMgmt.sql:

Otherwise, this is looking good.

afig commented 6 years ago

I believe this PR is now ready for a "merging" review. The unit tests now cover all of the functions defined in addClassDBRolesMgmt.sql, though the tests could use quite a bit of optimization in terms of code verbosity. Still, they pass and provide acceptable coverage.

The last few recommendations have been implemented, including removing the three views.

smurthys commented 6 years ago

Thanks @afig for making the changes. They look very good.

BTW, I recommend discussing function dropAllStudents in a C&C meeting. We could call that discussion "Why C++ runs circles around SQL" in readability, maintainability and execution efficiency. 👨‍🏫