Reputation: 43
Below is the part of the script that needs modifying. Currently it will match any word directly after the @ in the email address supplied by the user. I need it to be able to match any word either directly after the @ or with another word and dot (.) preceding, example: [email protected] should match domain, [email protected] should also match domain regardless of the .someword in front (which changes user to user and is there for some but not others.
PHP CODE:
preg_match('|@([0-9a-zA-Z]+)\.|i', $username, $match);
And below is the entire code with sensitive information changed for security.
<?php
// PHP code in child theme of WordPress multisite network functions.php
add_filter( 'authenticate', 'external_auth', 10, 3 );
add_filter( 'login_redirect', 'ds_login_redirect', 10, 3 );
function external_auth( $user, $username, $password ){
// Make sure a username and password are present for us to work with
if($username == '' || $password == '') return;
// Try to log into the external service or database with username and password
$args = array(
'method' => 'POST',
'timeout' => 45,
'redirection' => 5,
'httpversion' => '1.0',
'blocking' => true,
'headers' => array(),
'body' => array( 'username' => $username, 'password' => $password ),
'cookies' => array()
);
$ext_auth = wp_remote_post("http://auth-server:port-number/api-token-auth/",$args);
// if external authentication was successful
if($ext_auth['response']['code'] == 200) {
$userobj = new WP_User();
$user = $userobj->get_data_by( 'login', $username );
// Does not return a WP_User object :(
$user = new WP_User($user->ID);
// Attempt to load up the user with that ID
if( $user->ID == 0 ) {
// The user does not currently exist in the WordPress user table.
// If you do not want to add new users to WordPress if they do not
// already exist uncomment the following line and remove the user creation code
//$user = new WP_Error( 'denied', __("ERROR: Not a valid user for this system") );
// Setup the minimum required user information
$new_user_id = wpmu_create_user($username, $password, $username);
// A new user has been created
preg_match('|@([0-9a-zA-Z]+)\.|i', $username, $match);
$path = '/'.$match[1].'/';
$domain = 'the-wordpress-network-site.com';
// Figure out their blog to add permission to
$blog_id = get_blog_id_from_url ( $domain, $path );
// Specify their role
$role = 'subscriber';
// Give the user access to their blog.
add_user_to_blog($blog_id, $new_user_id, $role);
// Load the new user info
$user = new WP_User ($new_user_id);
}
}else if($ext_auth['response']['code'] == 400){
$user = new WP_Error( 'denied', __("ERROR: User/pass bad") );
}
// Comment this line if you wish to fall back on WordPress authentication
remove_action('authenticate', 'wp_authenticate_username_password', 20);
return $user;
}
function ds_login_redirect( $redirect_to, $request_redirect_to, $user )
{
if ($user->ID != 0) {
$user_info = get_userdata($user->ID);
if ($user_info->primary_blog) {
$primary_url = get_blogaddress_by_id($user_info->primary_blog) . 'index/';
if ($primary_url) {
//echo $primary_url; die();
wp_redirect($primary_url);
die();
}
}
}
return $redirect_to;
}
?>
Upvotes: 3
Views: 1422
Reputation: 43
My collegue found the answer, he is quite the PHP genius!
In place of this code in the question:
preg_match('|@([0-9a-zA-Z]+)\.|i', $username, $match);
$path = '/'.$match[1].'/';
$domain = 'the-wordpress-network-site.com';
Now the code reads:
$domain_end = explode('@', $username);
$match = explode('.', $domain_end[1]);
$domain = 'the-wordpress-network-site.com';
foreach ($match as $blog_key){
$path = '/'.$blog_key.'/';
$blog_id = get_blog_id_from_url ( $domain, $path );
if ($blog_id != 0) break;
}
That has solved the riddle much to my amazement and gratitude. Thanks anyway for all the suggestions and advice, I will still be here to ask many more questions in the future I don't doubt :)
Upvotes: 0
Reputation: 73
Note that the {2-4} restriction in C4ud3x's regex would disallow addresses from new/longer gTLDs which, although currently uncommon, should still be considered valid. You'll also want to consider users from countries where second-level domains are common, and not miss the 'real' domain because your regex captures just, say, .org.uk.
With the above in mind and borrowing from W3C's recommended regex, try:
[a-zA-Z0-9-_]*(\.[a-zA-Z0-9-_]{0,3})?\.([a-zA-Z0-9-_]{0,61})$
- see on RegExr
Of course, you should still validate the address in your PHP script before trying to extract the domain, so that you always capture a good result.
Upvotes: 0
Reputation: 3282
This would extract the domain out of the email:
([a-zA-Z0-9-\_]*)\.[a-zA-Z0-9\-\_]{2,4}$
@.+?([a-zA-Z0-9-\_]*)\.[a-zA-Z0-9\-\_]{2,4}$
([a-zA-Z0-9-\_]*)
this one groups the part before the last one, the domain obviously. Thats your match.
\.[a-zA-Z0-9\-\_]{2,4}$
this matches the last part of the string between 2 and 4 characters at the end of the string.(.com, .de, .it ...).
So you'll always get the 2nd last part in the string between dots.
Edit according comments:
As you want to ignore the fact, that domains are written in the 2nd last part, you would need to split the string into every part between dots and try to ping the domain if it is real.
Edit 2:
Check this article Wikipedia Email-format. There is a list of valid formats for emails. Every example in this article is covered by the regex I wrote. If you expect people typing in invalid mails like "[email protected]" (just to say -> invalid) you could also expect people writing "IhaveNoEmail" which wouldnt result in the right subdirectory either.
So I'm still on my point: Pick the regex or give me a real argument why the domain should be written somewhere else :).
Upvotes: 1