Hello,
I am currently working on a module for Drupal 4.5.x in which I would like to dynamically assign non-persistent roles to externally authenticated users. The way that I set out to do this was by catching the load operation in my module's hook_load function and then set or unset elements of $user->roles as required.
Unfortunately, this does not seem to work the way that I had expected it. I am able to manipulate the user object the way I want, and by tracing my way through the user.module code, I found that at the end of user_login() the user object still has the correct roles. This is on line 795 of user.module of version 4.5.2.
Note that to prevent the roles that I set from being overwritten, I moved user_module_invoke('load', $array, $user) in user_load. The last part of that function now looks like:
if (db_num_rows($result)) {
$user = db_fetch_object($result);
$user = drupal_unpack($user);
$user->roles = array();
$result = db_query('SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $user->uid);
while ($role = db_fetch_object($result)) {
$user->roles[$role->rid] = $role->name;
}
}
else {
$user = new StdClass();
}
user_module_invoke('load', $array, $user);
return $user;
I also need to point out that my users are authenticated against an external source, which makes things a little more complicated.
My feeling is that the user object gets reset/reloaded somewhere between completing the login sequence and presenting the first page.
For reference, the code that adjusts the user's roles (which I think is correct) is now
if ($op == 'load') {
// only address hyperborea users
if (!ereg('^(.*)@hyperborea.net$', $user->name, $match)) return;
$hyperuser = _get_hyper_user($match[1]);
if (sizeof($hyperuser) == 0) return;
if ($hyperuser['wizlevel'] > 0) {
$user->roles[WIZARD_ROLEID] = WIZARD_ROLELABEL;
} else {
if (array_key_exists(WIZARD_ROLEID, $user->roles)) {
unset($user->roles[WIZARD_ROLEID]);
}
}
if ($hyperuser['level'] > 0) {
$user->roles[PLAYER_ROLEID] = PLAYER_ROLELABEL;
} else {
if (array_key_exists(PLAYER_ROLEID, $user->roles)) {
unset($user->roles[PLAYER_ROLEID]);
}
}
}
If anyone could point me into the right direction; either by referring me to docs, code examples, or by helping me debug, I would greatly appreciate any help. I have a tendency of hanging out on #drupal (irc.freenode.net) as pa5kl.