Hi guys,

We're using logintoboggan on a project of ours. We've decided that instead of using the model that toboggan leans towards (Assign an less privileged 'interim' role for unconfirmed users, then move to authenticated on confirmation), we decided it made more sense for our use case for accounts to have the authenticated role (with less permissions) straight away, and assign a new role (more privileged) on confirmation.

Currently, we're doing this in a custom module - but i've created a patch against today's checkout of the 6.x CVS branch.

Basically, it adds a new field to the settings form, and adds a role on confirmation if it is selected.

I think this is definitely a feature worth implementing!

Comments

nicksanta’s picture

Also, if anyone is looking to replicate this functionality right now, you can do something like this..

<?php

/**
 * Define constants
 */
define('EXAMPLE_CONFIRMED_USER_ROLE', 'member');

/**
 * Implement hook_user
 */
function example_user($op, &$edit, &$account, $category = NULL) {
  // This is only fired when a user confirms their email address, logintoboggan style
  // A patch is currently in the logintoboggan queue: [d.o #628334]
  if ($op == 'update' && $account->logintoboggan_email_validated == TRUE) {
    $confirmed_rid = example_get_role_by_name(EXAMPLE_CONFIRMED_USER_ROLE);
    $roles = $account->roles + array($confirmed_rid => EXAMPLE_CONFIRMED_USER_ROLE);
    
    // we have to do this to stop an infinite loop, and also to allow lower weighted modules to possibly do something here
    $user = $account;
    unset($user->logintoboggan_email_validated);
    
    user_save($user, array('roles' => $roles));
  }
}

/**
 * Returns a role ID based on role name
 *
 * @param $name
 *  name of role to return
 * @return
 *  (int) Role ID
 */
function example_get_role_by_name($name) {
  return array_search($name, user_roles());
}

?>

Enjoy!

hunmonk’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev
Status: Needs review » Active

i'm not accepting new features for 6.x, so something like this would have to be considered for 7.x.

this feels like a hack to me. i'd rather not get into LT doing a bunch of role management -- we should only have to deal with one shifting role to implement the pre-authorized feature.

i've considered switching things around to make the pre-authorized workflow adding a role instead of removing the authenticated role dynamically, but the more i looked at it, the more it seemed fraught with issues. it is something i'll be discussing with my co-maintainer as part of the 7.x upgrade, but it would need a lot more work than this patch has done in order to do it properly.

also, you don't really need any changes in LT to do this cleanly in your own module. if you'll check _logintoboggan_process_validation(), you'll see this:

  // Allow other modules to react to email validation by invoking the user update hook.
  // This should only be triggered if LT's custom validation is active.
  if (!variable_get('user_email_verification', TRUE)) {
    $edit = array();
    $account->logintoboggan_email_validated = TRUE;
    user_module_invoke('update', $edit, $account);
  }

i welcome discussion here about the possibility of changing the basic workflow of the pre-authorized feature as i mentioned above, but it would involve a refactor, not a bolt-on.

nicksanta’s picture

Fair enough, it's always worth putting something out there for people to have a look at.

I'm not particularly passionate about the workflow within logintoboggan itself. It was pretty simple to implement in our custom module.

My boss just thought it was weird to escalate people's permissions by removing a role.. and when it's worded like that i feel more sympathetic to his point of view :P

nicksanta’s picture

Status: Active » Closed (fixed)
hunmonk’s picture

My boss just thought it was weird to escalate people's permissions by removing a role..

in practice, that's not the whole picture. what really happens at the end of the day when an account is confirmed is a role *switching* -- the pre-auth role is removed, and the auth role is added.

i'll grant you that it seems simpler in some ways to just start at the auth user level for pre-auth, then add a role for confirmed users, but believe me, because drupal bakes in the auth user role so deeply, this could lead to some tricky implementation details.

we'll see if we decide to go that direction in 7.x or not...

steveray’s picture

Jumping in here...
hunmonk, I'm not sure I understand what you are saying.

I thought that any user that is logged-in has Authenticated status, and that adding or removing other roles, including one called Pre-Authenticated doesn't remove their Authenticated status, only a log-out will do this.

Is this wrong?

Thanks.
Steve

nicksanta’s picture

@steveray - logintoboggan alters the normal user workflow. If you set an unconfirmed role, logintoboggan will forcefully remove the 'Authenticated user' role from unconfirmed users.

once they confirm their email address, they log in as authenticated users (as normal)

steveray’s picture

So, in the unconfirmed state, they are both not-Anonymous and not-Authenticated?

Thanks.

nicksanta’s picture

@steveray, yep - it kinda forcefully shoves an extra state inbetween the two core roles.

savmac’s picture

I've spent a few hours trying to achieve a login process just like what has been discussed here as well as other forum threads. I seems like it would be a pretty common need to have users assigned a specific role upon user registration. I installed the autoassignrole module to accomplish this but now a new user gets assigned the preauth role from logintoboggan as well as the role that the autoassignrole module gives them which then defeats the whole purpose.
I would very much like it if logintobbogan had a "post authenticated/confirmed" role selection in addition to the "non-authenticated" role selection option. This way an authenticated user could be assigned a specific role instead of just being a generic authenticated user.
The only way to currently accomplish this while using logintoboggan is to manually assign a new role to users after they have gone through the process of email authentication (unless I am missing something here - please help!)
Thanks

hunmonk’s picture

@savmac: i've included the information you need to implement post-validation code in comment #2 above.

Ralla’s picture

Why does user_email_verification need to be TRUE for the user_module_invoke hook to be run?

  // Allow other modules to react to email validation by invoking the user update hook.
  // This should only be triggered if LT's custom validation is active.
  $edit = array();
  $account->logintoboggan_email_validated = TRUE;
  user_module_invoke('update', $edit, $account);
  
hunmonk’s picture

@Raila: the code comment right above that code is:

  // Allow other modules to react to email validation by invoking the user update hook.
  // This should only be triggered if LT's custom validation is active.
BeMathis’s picture

hook_user() can fire with $op set to 'update' for reasons other than LT telling it to
LT function _logintoboggan_process_validation() passes its $account object with $account->logintoboggan_email_validated = TRUE

This way, you can have some unique happen only at the moment of validation and not every time a user is updated.

function my_module_name_user($op, $edit, &$account, $category = NULL) {
  switch($op){
    case 'update':
      if($account->logintoboggan_email_validated)
        //What happens when LT's _logintoboggan_process_validation() is finished
        break;
  }
}
pribeh’s picture

hmm. I'm looking for this exact feature since I've already constructed a site but would like to use the authenticated role as the non-authenticated role for new users who have yet to authenticate. I did the reverse when building the initial site, requiring no user email "authentication".

Since there's a bold warning that if I switch the non-authenticated role now (see below) I've decided that I'm going to try nicksanta's patch to get around this situation by adding a new role for authenticated users. That way, I can just add a new role for all existing users and hopefully be happily on my way. Unless ... someone else has might be able to suggest a better plan if approach.

WARNING: changing this setting after initial site setup can cause undesirable results, including unintended deletion of users -- change with extreme caution!

brunorios1’s picture

subscribing

goekhanc’s picture

Assigned: nicksanta » Unassigned
Category: feature » support
Status: Closed (fixed) » Active

is there any solution for drupal 7 ? I am not able to assign a new (more privileged) role after email validation succeeds.

the user is assigned the standard "authenticated user" role after the registration. but after email validation I want the user to be assigned to a more privileged role.

hunmonk’s picture

Status: Active » Closed (fixed)

i have no plans to implement this in 7.x. the approach discussed in #2 is still valid, and somebody could certainly write a module to do it. i would consider putting a module like that into LT's wild west contrib folder if somebody else provided a decent implementation -- feel free to reopen the issue in that case.

Alex Andrascu’s picture

Category: support » feature
Status: Closed (fixed) » Active

I think the patch in #1 can work nicely for D7 (no rocket science there and quite decent in my opinion)
It would make a nice feature. There's no need for wild west when there are only around 10 lines of code to add and allready provided. Unless you can state against that offcourse.

EDIT:
Actually scrap that: What i think we all need is to have this

logintoboggan will forcefully remove the 'Authenticated user' role from unconfirmed users.

line added somewhere visible
:)

aacraig’s picture

StatusFileSize
new24.51 KB

Taking you at your word from #2, I've done up a patch from your latest master branch.

As a side note, if I do
git clone --branch 7.x-1.x http://git.drupal.org/project/logintoboggan.git

I get the 6.x branch. I had to then
git checkout master

to get to the 7.x code.

Attached, find a patch which implements the add-on role, removing the pre-auth role. I've gone through the entire code base and replaced the pre-auth with the post-auth.

Since I don't know the module intimately, it's possible that I've missed spot, as I've trusted grep a lot to find the various places that needed to be altered.

I am able, though, to configure a role as the "add-on" role and see that a new user is simply added as an authenticated user, and after authentication gets added to the configured role.

Note that as a result, a lot of code can be removed (as I've done in the patch) as there are no longer any special case scenarios for the "pre-auth" role -- it's simply a case of setting a reduced permission set to the base authenticated user role, and then adding permissions to the new role that gets added after authentication.

I hope this is helpful.

3cwebdev’s picture

Drupal 7 version of code to use in custom module to add role to verified account


/**
 * Define constants
 */
define('EXAMPLE_CONFIRMED_USER_ROLE', 'ROLE_NAME'); // add role name here

/**
 * Implement hook_user
 */
function example_user_update(&$edit, $account, $category){
  // This is only fired when a user confirms their email address, logintoboggan style
  if (isset($account->logintoboggan_email_validated) && $account->logintoboggan_email_validated == TRUE) {    
    $confirmed_rid = example_get_role_by_name(EXAMPLE_CONFIRMED_USER_ROLE);    
    $roles = $account->roles + array($confirmed_rid => EXAMPLE_CONFIRMED_USER_ROLE);
    
    // we have to do this to stop an infinite loop, and also to allow lower weighted modules to possibly do something here
    $user = $account;
    unset($user->logintoboggan_email_validated);
    
    user_save($user, array('roles' => $roles));
  }
}

/**
 * Returns a role ID based on role name
 *
 * @param $name
 *  name of role to return
 * @return
 *  (int) Role ID
 */
function example_get_role_by_name($name) {
  return array_search($name, user_roles());
} 

marco_cruz’s picture

thanks alot!

ezoulou’s picture

#21 works like a charm. Thanks :-)

lemac889’s picture

#21 work like a charm for me to. thanks a lot!!

myDrupal2014_846824658246’s picture

Issue summary: View changes

I'm running into this: I'm using logintoboggan module for registration. A user can directly login with a username and password and get's the role "Pre Member". This role is a Non-authenticated role.

I also using Content Access. So now when the user want's to visit a Basic Page I get a Access Denied. I assuming Content Access is only looking for authenticed roles as in the account of the user says very clearly:

The user is assigned LoginToboggan's pre-authorized role, and is not currently receiving authenticated user permissions.Can somebody confirm this as I get the following message: Notice: Trying to get property of non-object in node_node_access() (line 3089 of D:\wamp\www\whaymeat\modules\node\node.module).

Does the code at #21 solves this?

Anonymous’s picture

I created a small sandbox module for the post authentication role. You can find it here https://www.drupal.org/sandbox/almare/2477911

It is inspired by quantumized. Thx for your code. It helped me to quickly solve my use case.

cthshabel’s picture

#21 works perfect!

New user has specific role that I defined after validating with login toboggan email.

thanks!

MarcusTis’s picture

Hi,

I am stil getting error message saying:

"For security reasons, the confirmation link is used only once."

I applyed #21 module and also tested #26 sandbox variant, I am running drupal core 7.39 so maybe the API changed?

Any ideas?

aaronbauman’s picture

Category: Feature request » Bug report

This ancient feature doesn't work in latest dev.