WordPress.org

Ready to get started?Download WordPress

Forums

Restrict Domains on a Per-Multisite Basis? (18 posts)

  1. foxymcfox
    Member
    Posted 1 year ago #

    I have a multisite set up and I'd like to be able to limit the registration of each one to a specific domain.

    So let's say I have sites set up for two companies: CompanyA.mysite.com and CompanyB.mysite.com.

    What I'd like to be able to do is allow the employees to register themselves to the site, but require they use their company email address to sign up. So I'm basically looking to whitelist ONLY @companyA.com addresses to register for the first site, and ONLY @companyB.com addresses for the second.

    All of the plugins out there don't seem to work on a multisite install and allows me -- when sandboxing -- to sign up from any domain. Any help?

    -Nick

  2. Huh. That's a VERY specialized setup and an interesting question.

    You actually don't want to limit registrations, because users belong to the network.

    What you want is to fork something like the 'Adding users to sites' trick I have at the end of http://halfelf.org/2012/multisite-registration/

    In your case, you'd add in a check to parse people's email and if companyB, add to companyb.mysite.com

  3. foxymcfox
    Member
    Posted 1 year ago #

    I am the king of specialized setups. I was here back when WordPress was blogging only, and finding fun ways to make it into a more robust CMS. So why make things easy on myself now? haha

    I've only had a chance to skim that article so far, but I want to go back and reread it thoroughly. If I'm not mistaken, what it's accomplishing is very similar to what I'm having the plugin "Join My Multisite." I may have to look into following your advice, rolling my own sign-up, then forking the code to run the domain check. That way I don't have to worry about the plugin losing support.

    Thanks for the help, it's why I love this community!

    And when I find my solution (It's not even a matter of if) I'll report back and post my results so that if there is even one other person who needs to make this implement this functionality, they can.

    -Nick

  4. FWIW, I wrote Join My Multisite based on the work I did in that post. But at the same time, it doesn't do the level of checks you want (i.e. limit per domain). :/

  5. foxymcfox
    Member
    Posted 1 year ago #

    That's fine, I'm fine doing some leg work. You've already given me a great base to work from with your write up and plugin.

    And like I said, any solutions I come up with will be posted here to be shared with the community.

    I hope you don't mind if I make my own mods to your plugin...

    -Nick

  6. I love when people fork and make it something even more awesome :D

  7. foxymcfox
    Member
    Posted 1 year ago #

    Cool, where here's where I stand with my crappy knowledge of PHP, so far.

    I've added the following to the settings.php file:

    Under "$new_options" I've added:

    $new_options['emailwhitelist'] = $_POST['jmm_emailwhitelist'];

    Then later, in the area where admin options are generated:

    <tr>
    <th scope="row"><?php _e('Allowed Email Domain:', 'helfjmm'); ?></th>
    <td><p>
    <input type="text" name="jmm_emailwhitelist" id="<?php echo $jmm_options['emailwhitelist']; ?>" value="<?php echo $jmm_options['emailwhitelist']; ?>">
    </p></td>
    <td><p class="description"><?php _e( 'Use this field to allow ONLY users from a particular email domain to register', 'helfjmm' )?></p></td>
    </tr>

    What I'm struggling with now is the validation in signuppage.php.

    What I was thinking was that I might be able to check it using strpos. Would it work if I did something like this, or am I overcomplicating things:

    $whitelist = $jmm_options['emailwhitelist'];
    $pos = strpos($useremail, $whitelist);
    
    if ($pos === false) {
        //code to disallow registration
    } else {
        //code to allow registration
    }

    Thoughts?

    I make stupid errors all the time in my code, (I'm thankful for debuggers everyday) so feel free to be brutal...I'm only a code "noodler" and not a programmer. Sometimes I need to have the information beaten into me. haha

    -Nick

    EDIT: Hmmm, doesn't seem to actually be validating. It's saying that any email address is invalid. I know this has to be some sort of stupid little thing I'm missing that's causing it, I just don't know what.

  8. Are the emails matching the subdomains always? I mean is it always companyA.domain.com and @companyA.com?

    $whitelist = $jmm_options['emailwhitelist'];
    
    $checkemail = explode("@", $useremail);
    $checkemail = $checkemail[(count($checkemail)-1)];
    if (in_array($checkemail, $whitelist)) {
        // Good
    } else {
        // Bad
    }
  9. foxymcfox
    Member
    Posted 1 year ago #

    The email domains may not always be character for character what the subdomain is, but there will always only ever be one email domain allowed per site...if that makes sense.

    That way, if someone sets up a site for XYZ Company and wants to used the company's full name in the domain but they use a different naming convention for their email domain it will be allowed. So they could be XYZCompany.site.com, with email addresses having the domain XYZComp.com.

    And after fooling around with that code, it doesn't seem to do the job either. Initially, I just swapped out "in_array" for "strpos" since I'm only checking one value, and that at least squashed the php error.

    However, it's still not working, but interestingly, I think my mistake may have been on the settings page. So my modification of your code above may still work.

    For whatever reason I cannot call the value of the whitelist. I've simply tried echoing it on the signup page and it returns empty single quotes instead of the dummy domain I put in. So now I'm basically back to square one.

    Is there another file within the plugin I need to modify to allow my whitelisted domain to be called like all of the existent parameters in the settings.php file?

    Thanks so much for all of your guidance. I really appreciate it.

    -Nick

    EDIT: I also wanted to add that the setting page holds the dummy value, so it seems it's being posted. But for some reason I just can't retrieve the value on the signup page, hence why all of my tests always show the email address as invalid.

  10. foxymcfox
    Member
    Posted 1 year ago #

    Okay, after a good night's sleep, I came at this with fresh eyes and made a few fixes. (It's amazing what a missing underscore can do) And it seems to be on the right track again:

    //Replace this with the whitelist value
            $whitelist = "whateverdomain.com";
    
    	$checkemail = explode("@", $user_email);
    	$checkemail = $checkemail[(count($checkemail)-1)];
    	$verifyemaildomain = strpos($checkemail, $whitelist);
    
    	if ($verifyemaildomain === false) {
               //Negative Result - replace with error
    	    echo "The string '$whitelist' was not found in the string '$checkemail'";
    	} else {
               //Positive Result - replace with completion
    	    echo "The string '$whitelist' was found in the string '$checkemail'";
    	}

    I'm just hardcoding the whitelist in for the time being until I can work out why the value isn't being pulled from the settings page, but at least it's progress.

    I'm going to have another dig around in the files to see what I can work out.

    -Nick

  11. foxymcfox
    Member
    Posted 1 year ago #

    MAN! I am a dummy sometimes. One line of code and I'm pulling values again!

    All I had to do was add this line:

    $jmm_options = get_option( 'helfjmm_options' );

    Inside of that function to be able to pull the value. I hate how the obvious problems end up being the ones that take up the most time.

    Here's where the signuppage.php additional code stands now:

    $jmm_options = get_option( 'helfjmm_options' );
    
    	$whitelist = $jmm_options['emailwhitelist'];
    
    	$checkemail = explode("@", $user_email);
    	$checkemail = $checkemail[(count($checkemail)-1)];
    	$verifyemaildomain = strpos($checkemail, $whitelist);
    
    	if ($verifyemaildomain === false) {
               //Negative Result - replace with error
    	    echo "The string '$whitelist' was not found in the string '$checkemail'";
    	} else {
               //Positive Result - replace with completion
    	    echo "The string '$whitelist' was found in the string '$checkemail'";
    	}

    I'm an idiot sometimes, but at least I can admit it. haha

    Now to take a short break and then add in the code to use this as validation criteria!

    Hopefully this is of use to some people out there looking to do something similar.

    -Nick

  12. foxymcfox
    Member
    Posted 1 year ago #

    Okay, I finally hit a wall where I think I'll need your guidance as the plugin creator.

    Here is the code as it stands now:

    $jmm_options = get_option( 'helfjmm_options' );
    
    	$whitelist = $jmm_options['emailwhitelist'];
    
    	$checkemail = explode("@", $user_email);
    	$checkemail = $checkemail[(count($checkemail)-1)];
    	$verifyemaildomain = strpos($checkemail, $whitelist);
    
    	if ($verifyemaildomain === false) {
    	    return $errors->add( 'invalidemaildomain', '<strong>ERROR</strong>: We are not currently accepting registrations from your email domain.'  );
    	}

    ...and it works!

    However it doesn't return the error message. It simply sends the user to a blank version of the signup page with no warning or alert. It does, however, prevent registration from all domains except the whitelisted domain.

    I was thinking that I may have to add some code to another section of the signuppage.php file, such as the "show_user_form()" function in order to have them sent back to the signup page with the accompanying error message, but I'm just not sure.

    Any advice on how to implement that? Once that's in place, this will work perfectly!

    Again, I really appreciate your help and guidance on this, it's been a HUGE help.

    -Nick

  13. Wow, nice job! If I get some time this week (heh, I'm still working at nearly 9 pm), I'll see if I have any brilliance about that.

  14. foxymcfox
    Member
    Posted 1 year ago #

    I hear that. I was still working at 10PM, my time, when I finally decided to call it a day...just because I thought a 15 hour day was a tad excessive after two 16 hours ones. haha

    I'm looking at adding a few other helpful elements some people should find useful as well:

    -Domain array, for people who need more flexibility than my one email domain per one subdomain
    -Easily customizable error messages
    -Possibly an optionally customizable redirect

    If anyone has any ideas as well, feel free to grab the code and have some fun. Mika, has really created a really robust base to fork from.

    Thanks again, for all of your help and fantastic plugin, Mika!

    -Nick

  15. foxymcfox
    Member
    Posted 1 year ago #

    Mika,

    New question, since you are the coolest person in the world and apparently never sleep:

    I'm currently looking at ways of limiting the access of members of one blog to other blogs, as the natural extension of my mods. I've tried extending the code I use that makes my subdomains private to people who aren't signed in by appending the following:

    add_action( 'wp', 'walled_garden' );
    
    function walled_garden() {
    
    	if ( is_user_logged_in() && !is_admin() && !is_user_member_of_blog() ) {
    		wp_redirect(***Redirect URL***));
    		exit;
    	}
    }

    ...and it doesn't seem to work.*

    There are only two things I can think of:

    A. I'm an idiot, missing something obvious (Like I'm using the wrong hook in my add_action or using the wrong functions).

    -OR-

    B. Something about the nature of the JMM or WordPress actually registers users as members of all sites, even if JMM prevents it from looking that way?

    I figured you might be able to provide some color on the second thought at least.

    As always, I really appreciate your guidance.

    -Nick

    * This is just one of many bits of code I've tried. Another one, borrowing from the code we used to limit registration to a domain, is:

    add_action( 'wp', 'walled_garden' );
    
    function walled_garden() {
    	global $current_user;
    	get_currentuserinfo();
    	$indiv_email = $current_user->user_email;
    	$jmm_options = get_option( 'helfjmm_options' );
    
    	$whitelist = $jmm_options['emailwhitelist'];
    
    	$checkemail = explode("@", $indiv_email);
    	$checkemail = $checkemail[(count($checkemail)-1)];
    	$verifyemaildomain = strpos($checkemail, $whitelist);
    
    	if (is_user_logged_in() && !is_admin() &&$verifyemaildomain === false) {
    		wp_redirect(***Redirect URL***);
    		exit;
    	}
    }

    And that too failed. So, I'm a tad stumped.

  16. is_admin() checks if you're in the admin screen or not, you want current_user_can('manage_options') instead :) That'll be a site admin (not network admin).

  17. foxymcfox
    Member
    Posted 1 year ago #

    I did that and it still wasn't working...so I thought to myself: If I was me, what is the simplest mistake I could be making right now?

    ...Turns out I didn't have the plugin activated on the secondary subdomain I was testing. hahaha

    *Facepalm*

    Thanks again for your help.

    -Nick

  18. foxymcfox
    Member
    Posted 1 year ago #

    And in the interest of sharing, here is where my additional code stands now in the pursuit of a locked down network site:

    add_action( 'wp', 'walled_garden' );
    
    function walled_garden() {
    	if ( is_user_logged_in() && !current_user_can('manage_options') && !is_user_member_of_blog() && !is_page('error')) {
    		wp_redirect(site_url('/error'));
    		exit;
    	}
    }
    
    function error_link() {
    	if(is_user_logged_in()&& !is_user_member_of_blog()) {
    		global $current_user;
      		$blogs = get_blogs_of_user( $current_user->id );
    
         		if($blogs) {
         	 		foreach ( $blogs as $blog ) {
             			echo '<strong>ERROR:</strong> You do not currently have permission to view this network. Please click<a href="http://' . $blog->domain . $blog->path .'">  here </a> to go to your network';
    			}
         		}
    }
    	else {
    		echo 'Hey!  How did you get here?';
    	}
    }
    
    add_shortcode('errortext', 'error_link');

    Again, I tagged this onto my private site plugin, based on jonradio's "jonradio Private Site" plugin. (I listed my changes in a thread in that plugin's support forum) Now, however, it allows you to redirect members of other blogs to an error page if they try to get into another site's "walled garden." This error page will tell them they don't have access and give them a link to their network. (Since I'm only letting people sign up for one blog at a time, the way I did this shouldn't be an issue, but you could modify the code to reset the array to only output the first result...OR just echo the array as a list if you have members who belong to other blogs)

    ...and then as an Easter egg, there's a customizable message if a member with access to a blog manually types in "error" after the link. For now, I just left mine as "Hey! How did you get here?"

    Hopefully someone out there can use this. If not, at least it's useful to me. If anyone has any suggestions or additions, feel free to add them.

    -Nick

    EDIT: Since I realize I didn't make it clear, this requires you to create a page on your sites called "error" and simply place the shortcode [errortext] on it. Through a hack or a plugin, then, just remove the link to the page from the navigation. Quick, dirty, and dead simple.

Topic Closed

This topic has been closed to new replies.

About this Topic