I've seen bits and pieces of this in a couple of issues, but I just wanted to note here for those also searching for this info — and please correct / clarify if I'm wrong — that, with mongodb modules enabled, roles are still stored primarily in MySQL.

While user records in Mongo do contain a "roles" object, it appears that there is never more than one role stored. For instance, if I have in my site a role called "Editor," a user with that role will have this in his user record:

"roles" : {
"1" : "authenticated user"

It is true that the user is an Authenticated User, but they also have another role, as well (I would expect an array of roles). My guess is that things work this way because roles are not set up as fields in MySQL; user_roles is its own table.

It looks like this actually trips things up in RC2, but not in the current dev version. With the RC2 version of mongodb_sessions enabled, it appears that non-anonymous users with roles other than "Authenticated User" do not actually appear to gain the permissions granted to them for their other roles.

In the "Editor" example above, even if the Editor has been granted the "Administer content" permission, he cannot edit content, view the Content list, etc. From my research, this is fixed in the current dev version.

Edit: I spoke too soon about the current dev. Upgrading to dev causes a PHP error when viewing a site. Can't say with any certainty whether the permissions issue is fixed.


tloudon’s picture

Assigned:Unassigned» tloudon

Current dev is broken b/c of e68769e. Line 113 in mongo_session.inc calls one of the deleted functions mongo_session_user_insert().

chx and I were talking about the need for those functions b/c of f115ae79, which rewrote a bit of that logic. The insert was causing a recursive Mongo error when mongo field storage was not enabled on my test site--which is why I noticed the issue and why it's a little more complicated than just reverting that commit.

Anyway, I'll see if I can write up a patch for this today or tomorrow.

WRT roles: you can see

function _mongodb_session_get_roles($account) {
  $roles = array();
  $roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
  $result = db_query("SELECT r.rid, r.name, ur.uid FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid IN (:uids)", array(':uids' => array($account->uid)));
  foreach ($result as $role) {
    $roles[(int) $role->rid] = $role->name;
  return $roles;

So all roles for a given uid are loaded from the users_roles table, in 7.x-1.0-rc2 these should be saved in fields_current.user by mongodb_session_user_update(). Authenticated user is hardcoded so that should be the minimum role for every user, but not the only one in the array if the user has other roles.

I think you're also asking where the role info is stored. Mongodb duplicates what's in the user roles table, but doesn't replace the mysql role or user related tables. AFAICT, the user module still relies on mysql/pg/etc and does all of the CRUD roles and other tables in hooks like user_save(), eg line 518 in user.module

majorrobot’s picture

Hi tloudon,

That makes a lot of sense (apologies for the delay in response — I've been neck-deep in development). I appreciate the clarification — and am heartened to hear that a patch will come for current dev!

sprice’s picture

I think that this might be the same as the issue here: #1668648: Undefined property: stdClass::$roles.

Is there any update on this? I'm running the newest of everything (core, context, and mongodb), and I'm getting the same error as in the other issue still.

jyee’s picture

Anyone looking to add the mongodb_session_user_insert() that was removed should look at the patches available on #1961728: undefined function mongodb_session_user_insert().

@tloudon @chx: I think one of the issues here is that mongodb_field_storage_field_storage_write() builds and saves a new entity assuming that the only properties the entity should have come from the base table or from fields. The problem of course is that users aren't quite entities because they have other properties, the most important of which is roles.

I wonder if instead of $new_entity starting as a new stdClass(), it might be better as a clone of $entity. Then overwrite properties with whatever the base table and fields use and possibly strip off anything that shouldn't be saved (e.g. $entity->original shouldnt be stored and would double storage size). I've attached a patch to help clarify. I think it helps solve the problem for users, but could complicate things for other entities.

jyee’s picture

Here's a less intrusive patch that only adds the roles property back to the new_entity. I'm not quite sure which is the "correct" way of resolving this (maybe neither), but I figured it's worth posting in case other people need a fix. I'd love to get more input from @chx or any of the other high level maintainers so we can get 7.x-dev working again.

jyee’s picture

Issue summary:View changes

I spoke too soon about the current dev. Upgrading to dev causes a PHP error when viewing a site. Can't say with any certainty whether the permissions issue is fixed.

majorrobot’s picture

Component:Session» Field storage
Category:Support request» Bug report
new861 bytes

Updating patch from #5, which only stored role ids in Mongo for non-authenticated-user roles:

"roles" : {
  "4" : "4",
  "5" : "5",
  "2" : "authenticated user"

This patch correctly uses role names instead:

"roles" : {
  "4" : "webmaster",
  "5" : "content editor",
  "2" : "authenticated user"
majorrobot’s picture

Status:Active» Needs review
majorrobot’s picture

Title:Clarification on Role Storage» Field Storage module does not store user roles

Changing title to more accurately reflect the issue.