MDL-56334 libraries: Addition of domain checker.
authorAdrian Greeve <adrian@moodle.com>
Mon, 10 Oct 2016 04:54:05 +0000 (12:54 +0800)
committerJake Dallimore <jake@moodle.com>
Wed, 26 Oct 2016 07:51:32 +0000 (15:51 +0800)
Added a function for checking if a domain is allowed
against a list of domains that could contain wildcards.

lib/classes/ip_utils.php
lib/tests/ip_utils_test.php

index d95f710..42abcb4 100644 (file)
@@ -185,4 +185,43 @@ final class ip_utils {
         }
         return false;
     }
+
+    /**
+     * Checks the domain name against a list of allowed domains. The list of allowed domains is may use
+     * wildcards that match {@link is_domain_matching_pattern()}.
+     *
+     * @param  string $domain Domain address
+     * @param  array $alloweddomains An array of allowed domains.
+     * @return boolean True if the domain matches one of the entries in the allowed domains list.
+     */
+    public static function is_domain_in_allowed_list($domain, $alloweddomains) {
+
+        if (!self::is_domain_name($domain)) {
+            return false;
+        }
+
+        foreach ($alloweddomains as $alloweddomain) {
+            if (strpos($alloweddomain, '*') !== false) {
+                if (!self::is_domain_matching_pattern($alloweddomain)) {
+                    continue;
+                }
+                // Use of wildcard for possible subdomains.
+                $escapeperiods = str_replace('.', '\.', $alloweddomain);
+                $replacewildcard = str_replace('*', '.*', $escapeperiods);
+                $ultimatepattern = '/' . $replacewildcard . '$/';
+                if (preg_match($ultimatepattern, $domain)) {
+                    return true;
+                }
+            } else {
+                if (!self::is_domain_name($alloweddomain)) {
+                    continue;
+                }
+                // Strict domain setting.
+                if ($domain === $alloweddomain) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }
index 455bb65..0fa9d39 100644 (file)
@@ -335,4 +335,43 @@ class core_ip_utils_testcase extends basic_testcase {
             ["fe80:::aaaa-dddd", false],
         ];
     }
+
+    /**
+     * Test checking domains against a list of allowed domains.
+     *
+     * @param  bool $expected Expected result
+     * @param  string $domain domain address
+     * @dataProvider data_domain_addresses
+     */
+    public function test_check_domain_against_allowed_domains($expected, $domain) {
+        $alloweddomains = ['example.com',
+                           '*.moodle.com',
+                           '*.per.this.penny-arcade.com',
+                           'bad.*.url.com',
+                           ' trouble.com.au'];
+        $this->assertEquals($expected, \core\ip_utils::is_domain_in_allowed_list($domain, $alloweddomains));
+    }
+
+    /**
+     * Data provider for test_check_domain_against_allowed_domains.
+     *
+     * @return array
+     */
+    public function data_domain_addresses() {
+        return [
+            [true, 'example.com'],
+            [false, 'sub.example.com'],
+            [false, 'example.com.au'],
+            [false, ' example.com'], // A space at the front of the domain is invalid.
+            [false, 'example.123'], // Numbers at the end is invalid.
+            [false, 'test.example.com'],
+            [false, 'moodle.com'],
+            [true, 'test.moodle.com'],
+            [false, 'test.moodle.com.au'],
+            [true, 'nice.address.per.this.penny-arcade.com'],
+            [false, 'normal.per.this.penny-arcade.com.au'],
+            [false, 'bad.thing.url.com'], // The allowed domain (above) has a bad wildcard and so this address will return false.
+            [false, 'trouble.com.au'] // The allowed domain (above) has a space at the front and so will return false.
+        ];
+    }
 }