WordPress.org

Make WordPress Core

Ticket #15706: 15706.5.diff

File 15706.5.diff, 9.3 KB (added by jeremyfelt, 8 years ago)
  • src/wp-includes/formatting.php

     
    29352935                        $value = array();
    29362936
    29372937                        foreach ( $domains as $domain ) {
    2938                                 if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) )
     2938                                if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.\*])+$|', $domain ) )
    29392939                                        $value[] = $domain;
    29402940                        }
    29412941                        if ( ! $value )
  • src/wp-includes/ms-functions.php

     
    373373 */
    374374function is_email_address_unsafe( $user_email ) {
    375375        $banned_names = get_site_option( 'banned_email_domains' );
    376         if ( $banned_names && ! is_array( $banned_names ) )
    377                 $banned_names = explode( "\n", $banned_names );
    378376
    379         $is_email_address_unsafe = false;
     377        $is_email_domain_in_list = is_email_domain_in_list( $user_email, $banned_names );
     378        /**
     379         * Filter a check for whether an email's domain is banned.
     380         *
     381         * @since 3.5.0
     382         *
     383         * @param bool $is_email_domain_in_list True if the email domain is banned.
     384         * @param string $user_email The email provided by the user at registration.
     385         */
     386        return apply_filters( 'is_email_address_unsafe', $is_email_domain_in_list, $user_email );
     387}
    380388
    381         if ( $banned_names && is_array( $banned_names ) ) {
    382                 $banned_names = array_map( 'strtolower', $banned_names );
    383                 $normalized_email = strtolower( $user_email );
     389/**
     390 * Checks an email address against a whitelist of allowed domains.
     391 *
     392 * This function checks against the Limited Email Domains list
     393 * at wp-admin/network/settings.php. The check is only run on
     394 * self-registrations; user creation at wp-admin/network/users.php
     395 * bypasses this check.
     396 *
     397 * @since 3.7.0
     398 *
     399 * @param string $user_email The email provided by the user at registration.
     400 * @return bool Returns true when the email address is allowed.
     401 */
     402function is_email_address_allowed( $user_email ) {
     403        $allowed_names = get_site_option( 'limited_email_domains' );
    384404
     405        // Any address is allowed when no whitelist is present
     406        if ( empty( $allowed_names ) ) {
     407                $is_email_address_allowed = true;
     408        } else {
     409                $is_email_address_allowed = is_email_domain_in_list( $user_email, $allowed_names );
     410        }
     411
     412        /**
     413         * Filter a check for whether an email's domain is allowed via whitelist.
     414         *
     415         * @since 3.7.0
     416         *
     417         * @param bool $is_email_address_allowed True when the email address is allowed
     418         * @param string $user_email The email provided by the user at registration.
     419         */
     420        return apply_filters( 'is_email_address_allowed', $is_email_address_allowed, $user_email );
     421}
     422
     423/**
     424 * Checks whether an email is on a whitelist/blacklist
     425 *
     426 * Used by is_email_address_unsafe() and is_email_address_allowed() to do
     427 * a wildcard-safe check of an email against an array of allowed/banned
     428 * domains.
     429 *
     430 * Any complete section of a URL (between the dots) can be represented by
     431 * a wildcard. Eg, 'test@foo.bar.com' will count as a match for '*.bar.com'.
     432 *
     433 * @since 3.7.0
     434 *
     435 * @param string $email The email address being checked
     436 * @param array|string $domain_list Domains to check against
     437 * @return bool Returns true when the email matches one of the domains on
     438 *   the list
     439 */
     440function is_email_domain_in_list( $email, $domain_list ) {
     441        if ( ! is_array( $domain_list ) ) {
     442                $domain_list = explode( "\n", $domain_list );
     443        }
     444
     445        $is_in_list = false;
     446
     447        if ( $domain_list && is_array( $domain_list ) ) {
     448                $domain_list = array_map( 'strtolower', $domain_list );
     449                $normalized_email = strtolower( $email );
    385450                list( $email_local_part, $email_domain ) = explode( '@', $normalized_email );
    386451
    387                 foreach ( $banned_names as $banned_domain ) {
    388                         if ( ! $banned_domain )
     452                foreach ( $domain_list as $domain ) {
     453                        if ( ! $domain ) {
    389454                                continue;
     455                        }
    390456
    391                         if ( $email_domain == $banned_domain ) {
    392                                 $is_email_address_unsafe = true;
     457                        if ( $email_domain == $domain ) {
     458                                $is_in_list = true;
    393459                                break;
    394460                        }
    395461
    396                         $dotted_domain = ".$banned_domain";
    397                         if ( $dotted_domain === substr( $normalized_email, -strlen( $dotted_domain ) ) ) {
    398                                 $is_email_address_unsafe = true;
     462                        $dotted_domain = ".$domain";
     463                        if ( $dotted_domain === substr( $email, -strlen( $dotted_domain ) ) ) {
     464                                $is_in_list = true;
    399465                                break;
    400466                        }
     467
     468                        if ( false !== strpos( $domain, '*' ) ) {
     469                                $domain_pattern = '|' . str_replace( '\*', '[a-zA-Z0-9-]+', preg_quote( $domain ) ) . '|';
     470                                preg_match( $domain_pattern, $email_domain, $matches );
     471                                if ( isset( $matches[0] ) && $matches[0] == $email_domain ) {
     472                                        $is_in_list = true;
     473                                        break;
     474                                }
     475                        }
    401476                }
    402         }
     477        }
    403478
    404         return apply_filters( 'is_email_address_unsafe', $is_email_address_unsafe, $user_email );
     479        return $is_in_list;
    405480}
    406481
    407482/**
     
    470545        if ( !is_email( $user_email ) )
    471546                $errors->add('user_email', __( 'Please enter a valid email address.' ) );
    472547
    473         $limited_email_domains = get_site_option( 'limited_email_domains' );
    474         if ( is_array( $limited_email_domains ) && empty( $limited_email_domains ) == false ) {
    475                 $emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) );
    476                 if ( in_array( $emaildomain, $limited_email_domains ) == false )
    477                         $errors->add('user_email', __('Sorry, that email address is not allowed!'));
    478         }
     548        if ( ! is_email_address_allowed( $user_email ) )
     549                $errors->add('user_email', __('Sorry, that email address is not allowed!'));
    479550
    480551        // Check if the username has been used already.
    481552        if ( username_exists($user_name) )
  • tests/phpunit/tests/ms.php

    Cannot display: file marked as a binary type.
    svn:mime-type = application/octet-stream
     
    839839         * @ticket 21570
    840840         */
    841841        function test_aggressiveness_of_is_email_address_unsafe() {
    842                 update_site_option( 'banned_email_domains', array( 'bar.com', 'foo.co' ) );
     842                update_site_option( 'banned_email_domains', array( 'bar.com', 'foo.co', '*.foo.org', 'foo.*.gov' ) );
    843843
    844                 foreach ( array( 'test@bar.com', 'test@foo.bar.com', 'test@foo.co', 'test@subdomain.foo.co' ) as $email_address ) {
     844                foreach ( array( 'test@bar.com', 'test@foo.bar.com', 'test@foo.co', 'test@subdomain.foo.co', 'test@bar.foo.org', 'test@foo.bar.gov' ) as $email_address ) {
    845845                        $this->assertTrue( is_email_address_unsafe( $email_address ), "$email_address should be UNSAFE" );
    846846                }
    847847
    848                 foreach ( array( 'test@foobar.com', 'test@foo-bar.com', 'test@foo.com', 'test@subdomain.foo.com' ) as $email_address ) {
     848                foreach ( array( 'test@foobar.com', 'test@foo-bar.com', 'test@foo.com', 'test@subdomain.foo.com', 'test@bar.baz.foo.org', 'test@foo.bar.baz.gov' ) as $email_address ) {
    849849                        $this->assertFalse( is_email_address_unsafe( $email_address ), "$email_address should be SAFE" );
    850850                }
    851851        }
     
    854854         * @ticket 25046
    855855         */
    856856        function test_case_sensitivity_of_is_email_address_unsafe() {
    857                 update_site_option( 'banned_email_domains', array( 'baR.com', 'Foo.co', 'barfoo.COM', 'BAZ.com' ) );
     857                update_site_option( 'banned_email_domains', array( 'baR.com', 'Foo.co', 'barfoo.COM', 'BAZ.com', '*.fOo.org', 'foo.*.Gov' ) );
    858858
    859                 foreach ( array( 'test@Bar.com', 'tEst@bar.com', 'test@barFoo.com', 'tEst@foo.bar.com', 'test@baz.Com' ) as $email_address ) {
     859                foreach ( array( 'test@Bar.com', 'tEst@bar.com', 'test@barFoo.com', 'tEst@foo.bar.com', 'test@baz.Com', 'test@bAR.foo.org', 'test@fOO.bar.gov' ) as $email_address ) {
    860860                        $this->assertTrue( is_email_address_unsafe( $email_address ), "$email_address should be UNSAFE" );
    861861                }
    862862
    863                 foreach ( array( 'test@Foobar.com', 'test@Foo-bar.com', 'tEst@foobar.com', 'test@Subdomain.Foo.com', 'test@fooBAz.com' ) as $email_address ) {
     863                foreach ( array( 'test@Foobar.com', 'test@Foo-bar.com', 'tEst@foobar.com', 'test@Subdomain.Foo.com', 'test@fooBAz.com', 'test@bar.bAZ.foo.org', 'test@foo.BAr.baz.gov' ) as $email_address ) {
    864864                        $this->assertFalse( is_email_address_unsafe( $email_address ), "$email_address should be SAFE" );
    865865                }
    866866
    867867        }
     868
     869        function test_is_email_address_allowed() {
     870                update_site_option( 'limited_email_domains', array( 'bar.com', 'foo.co', '*.foo.org', 'foo.*.gov' ) );
     871
     872                foreach ( array( 'test@bar.com', 'test@foo.bar.com', 'test@foo.co', 'test@subdomain.foo.co', 'test@bar.foo.org', 'test@foo.bar.gov' ) as $email_address ) {
     873                        $this->assertTrue( is_email_address_allowed( $email_address ), "$email_address should be UNSAFE" );
     874                }
     875
     876                foreach ( array( 'test@foobar.com', 'test@foo-bar.com', 'test@foo.com', 'test@subdomain.foo.com', 'test@bar.baz.foo.org', 'test@foo.bar.baz.gov' ) as $email_address ) {
     877                        $this->assertFalse( is_email_address_allowed( $email_address ), "$email_address should be SAFE" );
     878                }
     879
     880                update_site_option( 'limited_email_domains', '' );
     881
     882                foreach ( array( 'test@foobar.com', 'test@foo-bar.com', 'test@foo.com', 'test@subdomain.foo.com', 'test@bar.baz.foo.org', 'test@foo.bar.baz.gov' ) as $email_address ) {
     883                        $this->assertTrue( is_email_address_allowed( $email_address ), "$email_address should be SAFE" );
     884                }
     885        }
     886
    868887        /**
    869888         * @ticket 21552
    870889         * @ticket 23418