For some time now, users who are granted CVS access for a project can also edit the project node and create releases. This is controlled through the project_check_admin_access() function in project.module. If a somewhat unusual string of events takes place, however, this might not be ideal.
Here's the string of events:
- User 'maint' creates ProjectA.
- User 'comaint' applies for CVS access to help co-maintain ProjectA and is granted access by the d.o admins.
- User 'maint' grants user 'comaint' CVS access to ProjectA. User 'comaint' now has permission to edit the ProjectA node and create releases.
- User 'comaint' does something crazy that gets his CVS account disabled by the d.o admins.
- User 'comaint' can still act as a co-maintainer for the project because the default value for $cvs_account in
project_check_admin_access()is $cvs_account=TRUE, even though that's not actually checked.
On the other hand, if user 'maint' tried to give user 'comaint' CVS access to the project but user 'comaint' had his CVS access disabled, an error would be returned.
I'm testing this on my system, so it's possible that things are set up slightly different on d.o and so this doesn't happen.
I'm not sure if this is undesired behavior or not, since the project maintainer (user 'maint') could just revoke access to user 'comaint' for the project, but maybe it would be best to have this be automatic.
Feel free to mark this as by design if you think that's appropriate. If you do think it's a bug, I've patched the project_check_admin_access() function as so and this seems to keep this from happening. I can roll a patch if you want me to:
function project_check_admin_access($project, $cvs_access = NULL) {
global $user;
if (empty($user->uid)) {
return FALSE;
}
if (!isset($cvs_access)) {
if (db_num_rows(db_query("SELECT * FROM {cvs_accounts} WHERE uid = %d AND status = %d", $user->uid, 1))) {
$cvs_access = TRUE;
}
else {
$cvs_access = FALSE;
}
}
$project_obj = is_numeric($project) ? node_load($project) : $project;
if (!isset($project_obj) || $project_obj->type != 'project_project') {
return FALSE;
}
if (user_access('administer projects')) {
return TRUE;
}
if (user_access('maintain projects')) {
if ($user->uid == $project_obj->uid) {
return TRUE;
}
if (project_use_cvs($project) && $cvs_access) {
if (db_num_rows(db_query("SELECT * FROM {cvs_project_maintainers} WHERE uid = %d AND nid = %d", $user->uid, $project_obj->nid))) {
return TRUE;
}
}
}
return FALSE;
}
I haven't looked everywhere else that project_check_admin_access() is called, however, so this might cause problems that I haven't thought of.
AC
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | project_check_admin_access.txt | 1.03 KB | aclight |
Comments
Comment #1
dwwyup, that's a bug. a patch would be lovely. while we're at it, we should probably indicate these people's CVS account is disabled on the CVS access tab, to alert project owners, that the user can't commit since the account is disabled. an audit of other places that call project_check_admin_access() would be great, too. thanks. ;)
Comment #2
aclight commentedRegarding an audit of
project_check_admin_access(), the function itself if called from project.inc and project_release.module. My change in the function will only change the behavior of the function when the second parameter to the function ($cvs_access) is NULL. This is the case in the following places:project_project_access()when$op == 'update'project_release_access()when$op == 'update'project_release_form()project_release_get_releases()project_release_project_download_table()So this fix will effectively make sure that a user is both a maintainer of the project AND that the user currently has CVS access when deciding to allow or deny the following actions:
I still haven't written code for the UI that alerts a project maintainer that another maintainer has lost his CVS access, and thus project maintainer status, and so there's no patch yet. I'll try to work on that soon. But it doesn't look like applying this patch will break any behavior--only fix it.
AC
Comment #3
aclight commentedassigning myself to this
Comment #4
aclight commentedThe attached patch fixes the actual access checking in
project_check_admin_access(). I've created a separate issue for the cvslog module at http://drupal.org/node/158813 that changes the CVS access page as requested in #1.AC
Comment #5
dwwPatch needed work:
A) This is wrong:
Should be:
B) Now that the code only fires if cvs.module is enabled, we should use the CVS_APPROVED constant, instead of hard-coding 1.
C) Whitespace troubles.
D) Comment formatting.
However, since I'm on a roll cleaning out the patch-needs-review queue, I just fixed these myself.
Also, I realized that xcvs-* doesn't immediately reject CVS activity by someone with their CVS account disabled. :( Instead, it waits until the passwd file is regenerated and then CVS itself will prevent the activity. This is lame, so I changed cvslog/xcvs/xcvs-db.php to check for approved accounts when mapping CVS usernames into Drupal uids, so that we effectively disable all access immediately.
Tested heavily, and committed my modified patch and the change to xcvs-db.php to HEAD and DRUPAL-4-7--2.
Comment #6
aclight commentedThat's what I had done originally, but when I did so I got some weird errors, even though I had cvslog enabled. But I didn't investigate very thoroughly, so I might have been doing something stupid :)
If by chance this still doesn't work on my system, I'll try to figure out why to make sure that it's nothing with the code.
Thanks
AC
Comment #7
(not verified) commented