WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] [closed] Create local users in each subdomain (26 posts)

  1. sontru
    Member
    Posted 1 year ago #

    Is it possible to have users local to each subdomain?

    What I want to do is to set up a multisite with global (admin of subdomain) users created and authenticated via Shibboleth and allow users (non-admins) created locally for any subdomain that need users. Has anyone set up anything similar to this and how?

    P.S. Has anyone gotten the Shibboleth plugin to work with this current MS (3.4.2) version?

  2. By default users belong to the network.

    They have 'subscriber' access to all sites (read-only and comment).

    If you need more roles, they get provided ad hoc.

    So ... that's kind of similar?

  3. sontru
    Member
    Posted 1 year ago #

    Thanks for the reply, but not really.

    I wonder if it is possible add a prefix or suffix to the user/login name when a user is created with a subdomain..? Does anyone know of such a plugin?

    No response from anyone using Shibboleth sign-on? (Do I need to make another post asking..?)

  4. sontru
    Member
    Posted 1 year ago #

    Right, I've managed to get the Shibboleth plugin working! Yay!

    Could anyone give me a pointer to a user creation plugin that can put a prefix or suffix (of that subdomain) on the username when a user is created?

  5. sontru
    Member
    Posted 1 year ago #

    Right, I've managed to break Shibboleth login! :(

    Looks like the WP Email Login plugin is breaking Shib - anyone know why and how to fix this?

    The idea is that (if I can get prefix/suffix added to a created user, then they can login using their email instead of an odd login name. But if the email login breaks Shib, then it won't work.

    Has anyone got any suggestions?

  6. I wonder if it is possible add a prefix or suffix to the user/login name when a user is created with a subdomain..? Does anyone know of such a plugin?

    Probably. You'd want to extend something like this:

    <?php
    global $blog_id;
    if ( $blog_id == 2 ) {
    
      function sontru_activate_user( $user_id, $password, $meta )
      {
     // Something to change the user name...
    }
      add_action( 'wpmu_activate_user', 'sontru_activate_user', 10, 3 );
    }
    ?>

    This would say 'Anyone from blog 2 gets something changed'

  7. sontru
    Member
    Posted 1 year ago #

    Thanks for the reply and suggestion (was beginning to think I was just talking to myself!) I've tried various pieces of code and have not made any success :(

    I have found that if I insert the following code:

    $hostAddress = explode('.',$_SERVER['HTTP_HOST']);
            $user .= '_' . $hostAddress[0];

    directly into the function wpmu_signup_user in the file wp-includes/ms-functions, it does what I want, as:

    function wpmu_signup_user($user, $user_email, $meta = '') {
            global $wpdb;
    
            $hostAddress = explode('.',$_SERVER['HTTP_HOST']);
            $user .= '_' . $hostAddress[0];
    
            // Format data
            $user = preg_replace( '/\s+/', '', sanitize_user( $user, true ) );
            $user_email = sanitize_email( $user_email );
            $key = substr( md5( time() . rand() . $user_email ), 0, 16 );
            $meta = serialize($meta);
    
            $wpdb->insert( $wpdb->signups, array(
                    'domain' => '',
                    'path' => '',
                    'title' => '',
                    'user_login' => $user,
                    'user_email' => $user_email,
                    'registered' => current_time('mysql', true),
                    'activation_key' => $key,
                    'meta' => $meta
            ) );
    
            wpmu_signup_user_notification($user, $user_email, $key, $meta);
    }

    Unfortunately this is not a plugin, as I have struggled to find the appropriate hook and code to do this job. Any ideas what the hook and the plugin code would be to do the same thing?

  8. You hook like this:

    add_action( 'wpmu_signup_user', 'sontru_signup_user', 10, 3 );

    And then make

    function sontru_activate_user( $user, $user_email, $meta = '' ) {
    
            $hostAddress = explode('.',$_SERVER['HTTP_HOST']);
            $user .= '_' . $hostAddress[0];
    }

    You may need a return in there, but that's the basic idea.

  9. sontru
    Member
    Posted 1 year ago #

    Thanks for that. I thought I had already tried that and it did work. So I tried it again and... nope does not work for some reason. My code is in a plugin file which fixes the 'login name must be a minimum of 4 characters' error, and an email login code which works. (Included here in case anyone want these problems fixed too...)

    <?php
    /*
    Plugin Name: Email Login, Remove Min 4 Chars Login Name, Add Subdomain Suffix
    Plugin URI:
    Description: Does all of the above!
    Author: sontru
    Version: 1.3.0
    Author URI:
    */
    
    function login_with_email_address($username) {
            $user = get_user_by_email($username);
            if(!empty($user->user_login))
                    $username = $user->user_login;
            return $username;
    }
    add_action('wp_authenticate','login_with_email_address');
    
    function remove_username_char_limit($result) {
      if ( is_wp_error( $result[ 'errors' ] ) && !empty( $result[ 'errors' ]->errors ) ) {
    
        // Get all the error messages from $result
        $messages = $result['errors']->get_error_messages();
        $i = 0;
        foreach ( $messages as $message ) {
    
          // Check if any message is the char limit message
          if ( 0 == strcasecmp("Username must be at least 4 characters.", $message)) {
            // Unset whole 'user_name' error array if only 1 message exists
            // and that message is the char limit error
            if ( 1 == count($messages) ) {
              unset( $result['errors']->errors['user_name'] );
            } else {
              // Otherwise just unset the char limit message
              unset( $result['errors']->errors['user_name'][$i] );
            }
          }
    
          $i++;
        }
      }
    
      return $result;
    }
    add_action('wpmu_validate_user_signup', 'remove_username_char_limit');
    
    function add_suffix_to_login($user, $user_email, $meta = '')
    {
            $hostAddress = explode('.',$_SERVER['HTTP_HOST']);
            $user .= '_' . $hostAddress[0];
            return $user;
    }
    add_action('wpmu_signup_user', 'add_suffix_to_login',10,3);
    
    ?>

    <strike>Is there a different between a calling add_action before defining the function and after it?</strike> Just tried this and no difference - still does not have the desired effect.

  10. Okay... Let's step back :)

    try making your add_suffix code just add a letter or the underscore. See if that works.

  11. sontru
    Member
    Posted 1 year ago #

    Nope. The code being:

    function add_suffix_to_login($user, $user_email, $meta = '')
    {
    //        $hostAddress = explode('.',$_SERVER['HTTP_HOST']);
            $user .= '_'; // . $hostAddress[0];
            return $user;
    }
    add_action('wpmu_signup_user', 'add_suffix_to_login',10,3);

    and no underscore is added. In fact, this code does not even work:

    function add_suffix_to_login($user, $user_email, $meta = '')
    {
    //        $hostAddress = explode('.',$_SERVER['HTTP_HOST']);
    //        $user .= '-' . $hostAddress[0];
            $user = 'testusersontru';
            return $user;
    }
    add_action('wpmu_signup_user', 'add_suffix_to_login',10,3);

    which means the function is not being called. I'm a newbie at this but is there a hook for this function 'wpmu_signup_user' for the action to be added?

  12. Reading... Cause I'm an idiot. "This function is used when user registration is open but new site registration is not."

    *facepalm*

  13. sontru
    Member
    Posted 1 year ago #

    Is that a no? What can I do instead? Is hacking ms-functions.php my only choice?

  14. Shane Gowland
    Member
    Posted 1 year ago #

    Is hacking ms-functions.php my only choice?

    Hacking core is a really, really bad idea (kittens will actually be murdered). You're opening yourself up to major headaches in the future.

  15. No it's just that wpmu_signup_user is wrong.

    I'm not 100% sure what right is. Maybe wpmu_create_user?

    http://codex.wordpress.org/WPMU_Functions/wpmu_create_user

  16. sontru
    Member
    Posted 1 year ago #

    The reason I am not using wpmu_activate_user (initially suggested) is because of the validation/activation part.

    There is a wp_signups table that maintains and reserves unique login names. If this table does not get updated with the login_subdomain then there will be problems with subdomains creating users, such as billy_domain1 and billy_domain2. These login named will be treated as the same if they don't get suffixed before it goes into the wp_signups table.

    I will verify this if I get the plugin to work with wpmu_create_user.

    EDIT: I don't think this would work. I used to have my code inserted directly into 'function wpmu_activate_signup($key)' at about //HERE!:

    $user_id = username_exists($user_login);
    
            if ( ! $user_id )
            {
                    //HERE!
                    $hostAddress = explode('.',$_SERVER['HTTP_HOST']);
                    $user_login .= '_' . $hostAddress[0];
                    $user_id = wpmu_create_user($user_login, $password, $user_email);
            }
            else
                    $user_already_exists = true;
    
            if ( ! $user_id )
                    return new WP_Error('create_user', __('Could not create user'), $signup);

    i.e. before wpmu_create_user is called. Although this added the suffix to the $user_login, this username does not appear in the wp_signups table.

  17. What about constructing your own signup page instead, and hard coding it in there? I'm at a loss to which function you'd want here :( I'd have to play around with all of them.

  18. sontru
    Member
    Posted 1 year ago #

    Yes, it may have to come down to this (although this sounds like a bigger project!)

    How do I start going about replacing the 'Add New User' admin page in the subdomain only? Any pointers would be appreciated...

    P.S. I think I just need to be able to call the function that inserts the user into the wpmu_signups table, which I think is wpmu_signup_user, but I don't seem to be able to hook up there.

  19. jkhongusc
    Member
    Posted 1 year ago #

    sontru -
    Sorry I am late to this discussion but I do not completely understand your requirements. It seems you want two authentication systems: shibboleth and local (WP). Anyone who authenticates via Shibboleth is created an WP admin account with which you want to append the subdomain to the username... is that correct? What kind of user attributes are you getting from Shibboleth - uid, email?

    Let me tell you a bit about our multisite(domain) WP system at USC. At USC we use Shibboleth as our main sign-on and ldap as a secondary auth system. For WP, we configured it to use all three systems: Shib, ldap, and local. When a user logs in, WP attempts to log the user into each system until successful. We had to write our own Shib and ldap auth WP plugin - using other plugins as a template. However we do not auto-provision users. We also wrote a "bulk" user plugin which allows us to create WP accounts for a list of users, giving the user privilege to a specific blog. Afterwards the user can log into that site using Shibboleth or ldap. We only use local authentication for special cases, for example consultants who are not in any USC system.

    Let me know if anything interests you and I can provide more info.

  20. sontru
    Member
    Posted 1 year ago #

    No you are not too late - thanks for the interest.

    OK, this is a short breakdown. I had to set up a WP MS system and integrate it with our SSO - Shibboleth. I have done this now, and it works. However, I have found that with MS, users are all global. We want local users (users created and maybe restricted to a specific subdomain) as well as global users (Shib). This is so 'external' users can be created and allow to login/contribute within the subdomains.

    Now because users who login using Shib gets an account created automatically, what happens if a subdomain creates a user (login name) that is the same as the Shib user? (Note the two users are different people).

    So this is the problem, which I think can be solved with this. Shib users login and get created as per plugin. User created in a subdomain gets the login name suffixed with the subdomain.

    So Shib user 'bob' is different from user bob_subdomain1, different from bob_subdomain2.

    I think one problem to understand is that we are allowing Admins of our subdomain the ability to create users. So they could create login names that could potentially clash with the 'global' Shib logins. Also, we can not guarantee that a subdomain user created today with a unique login name that does not clash with Shib user, will be the same user that get created in Shib tomorrow...

  21. jkhongusc
    Member
    Posted 1 year ago #

    You have a name space issue and you want to limit users to a specific subdomain. The latter requirement kind of conflicts with WP MS. One possibility is to use email address as the username (at least for Shib) - that would solve name space problems.

    I see a few potential problems with appending subdomains onto usernames:
    - Most likely no one else has done this and you will need to do some plugin development.
    - For the username, will the subdomain be shown to the user so that they need to provide the 'username_subdomain' to login or is the subdomain "hidden"
    - Changing username will confuse the user and admin. For example: emails sent to the user will show their username (that includes the subdomain), users will see their username in the profile, etc. It will be an administrative problem.
    - What happens if you change the subdomain?
    - I see potential problems with authentication, depends on how you design it.

    The way I see it, you may need to create two plugins: one for authentication and another for creating users. Depends on whether you want to hide subdomain in the user names and if you will have site admins follow a certain policy when creating users. There might be other issues I have not thought of.

  22. sontru
    Member
    Posted 1 year ago #

    Thanks for the ideas, but I think I have it solved ;) You are right that I have a namespace clash - out of interest, if you use Shibboleth (assuming using the same plugin as everybody else) and also have local users - how do you resolve the namespace clash problem? (Say, what happens in your case, if you have a local user in your database - Bob, then comes along a user who logs in via Shibboleth authentication who's login name is als Bob - what happens?)

    My solution is (1) 'local' wp user who can login using Shib, (2) email login enabled, and (3) local wp users with domain suffix (who might be restricted only to the subdomain they were created for - depending if I can find the right user management plugin).

    The locally created subdomain users do not have their login name changed - they are created by the admin who will be informed that the user they are creating has the suffix added to the login name (and the email that goes to the user will inform them that their login is bob_subdomain) no confusion there. Email login is enabled so users can use their email address to login (so so fuss there with remembering login names).

    I have hacked the ms-functions.php so that it appends the suffix to users created in/for a subdomain - and this works. The remaining issue is how to write a plugin to do this so that whenever the WP MS code is changed, I do not need to constantly hack it again...

    Ipstenu (Mika Epstein) and I have been trying to locate the hook that will allow me to write a plugin, and we have concluded that it is not as simple as we might expect. We think the plugin will need to replace the Create New User admin (in the subdomain) page, which might be a good thing because that would be where I inform them that they are creating local (to the subdomain user) whose login name will be suffixed with the name of their subdomain. (But who can login using their email address if they want to or can't remember the strange login name.)

    It will take some work to get a plugin to do the simple task of adding the subdomain suffix, so for the meantime I will leave the hack code in the ms-functions.php to do its work, and hope I don't need to upgrade MS WP anytime soon...

  23. jkhongusc
    Member
    Posted 1 year ago #

    sontru -
    We avoid namespace clashes as 99% of our users are USC members. The 1% that are not, we use email address as their username. FYI, we can also assign Shibboleth user's with a WP password, so if Shibboleth service is out, a shib user (really admins only) can use local auth to gain access.

    I see your dilemma. Here are a few suggestions that I think would be better than modifying core WP files (kind of a hassle every time you upgrade):
    1) Add a plugin to add javascript to the header. With javascript you can grab the content from the username field and append the subdomain.
    2) wpmu_new_user - this is a hook that is called after the user has been created. Not sure if it is possible to change the username of an existing user. If it is possible, then you could use this hook to append the subdomain to the username
    3) Modify the add user file (new-user.php?)... bad but slightly better than modifying ms-functions.php

  24. anandbala
    Member
    Posted 1 year ago #

    By default users belong to the network.

    They have 'subscriber' access to all sites (read-only and comment).

    If you need more roles, they get provided ad hoc.

    So ... that's kind of similar?

    I am not wanted this option , my need is every subdomain is seperate site so need not to have access to other subdomain .

    could u help me

  25. sontru
    Member
    Posted 1 year ago #

    I don't know what version of WordPress Multisite you are using, but for me with 3.4.2, network users are not members of any subdomain unless you make them so (either manually or using a plugin).

    I am currently writing a plugin to replace the add new user page but this is taking me a while. In the meantime I have modified the wpmu_signup_user function as detailed above (to add the domain suffix).

  26. sontru - it's the same in all WP (except 3.0, which make users members of the main site)

    I am not wanted this option , my need is every subdomain is seperate site so need not to have access to other subdomain .

    That's how it's supposed to work, anandbala. If you need help with that, please post your own topic, though.

Topic Closed

This topic has been closed to new replies.

About this Topic