50 Commits

Author SHA1 Message Date
Luuk Verhoeven
26669e73f1 Merge pull request #11 from LdesignMedia/86c3hkgy9-update-moodle-50
Update #86c3hkgy9 - Update Moodle Version 50
2025-05-27 14:43:41 +02:00
Jan Choroś
e7e5cbe91d Update #86c3hkgy9 - Update Moodle Version 50 2025-05-22 15:35:21 +02:00
Luuk Verhoeven
d56173f6b8 Update version.php 2025-04-04 10:21:42 +02:00
Luuk Verhoeven
c9b5e6cb7d Merge pull request #10 from LdesignMedia/86c2xmcmw-upgrade-45
86c2xmcmw upgrade 45
2025-04-04 10:17:52 +02:00
Luuk Verhoeven
fcfa4eb773 Delete .github/workflows/AppScan.yml 2025-04-04 10:17:17 +02:00
Nihaal Shaikh
b98a63e1f4 Update #86c2xmcmw - readme and version file updated 2025-04-04 09:25:26 +02:00
Nihaal Shaikh
a836731b24 Update #86c2xmcmw - upgraded plugin to M45 2025-04-04 09:19:36 +02:00
Luuk Verhoeven
c2f5e7e22c Update language file for phpcs 2024-07-20 22:54:06 +02:00
Luuk Verhoeven
761d643479 Update version 2024-07-20 22:22:05 +02:00
Luuk Verhoeven
5ef0c811c0 Update remove sonar cloud 2024-07-20 22:14:31 +02:00
Luuk Verhoeven
6633439651 Update RegExp to not exceed 132 characters 2024-07-20 22:12:54 +02:00
Luuk Verhoeven
4b4fced58b Add auto release 2024-07-20 15:08:33 +02:00
Luuk Verhoeven
8ae54193d2 Update code and environment checks 2024-07-20 15:01:12 +02:00
Luuk Verhoeven
26bbc1cbdb Add CI workflows 2023-09-26 13:41:32 +02:00
Luuk Verhoeven
5d615ddb24 Add CI workflows 2023-09-26 13:31:05 +02:00
Luuk Verhoeven
5e2566fbba Add CI workflows 2023-09-26 13:25:29 +02:00
Luuk Verhoeven
96c93c4096 Add CI workflows 2023-09-26 13:24:54 +02:00
Luuk Verhoeven
d302aa626a Merge remote-tracking branch 'origin/master'
# Conflicts:
#	.github/workflows/ci.yml
2023-09-26 13:23:32 +02:00
Luuk Verhoeven
787dba81f0 Add CI workflows 2023-09-26 13:23:17 +02:00
Luuk Verhoeven
f24ef270a5 Update version.php 2022-06-04 11:08:38 +02:00
Luuk Verhoeven
0e7ec99338 Merge pull request #7 from MFreakNL/#2am8vvp_test_moodle4
Moodle 4.0 release
2022-05-30 23:31:11 +02:00
Hamza Tamyachte
3b489f3406 Add Moodle 4.0 Support 2022-05-30 14:36:35 +02:00
Hamza Tamyachte
84ea4a9165 Add Moodle 4.0 Support 2022-05-30 11:38:27 +02:00
Vincent Cornelis
9d6f7e51b9 Add changelog 2022-02-14 15:24:32 +01:00
Vincent Cornelis
855f8fecaa Update condition.php
indentation fix
2022-02-11 17:48:54 +01:00
Vincent Cornelis
30459042d7 Update version.php
Bumped version number
2022-02-11 17:42:18 +01:00
Vincent Cornelis
a6b22c06e3 Merge pull request #5 from juacas/master
Support ipv4 ranges. Issue #4
2022-02-11 17:40:14 +01:00
Juan Pablo de Castro (UVa)
e44acd4a7f Support ipv4 ranges. 2022-02-01 08:41:47 +00:00
Vincent Cornelis
4754b1e03e Merge branch 'moodle-release' 2021-12-15 11:26:29 +01:00
Vincent Cornelis
54ac7002d8 bumped versionnumber 2021-12-15 11:26:08 +01:00
Vincent Cornelis
5d25933dfb bumped versionnumber 2021-12-09 13:54:49 +01:00
Vincent Cornelis
28f6d4603b added end-of-lines 2021-12-09 13:42:54 +01:00
Vincent Cornelis
527831df6b add github workflow moodle-release 2021-12-09 13:38:46 +01:00
Luuk Verhoeven
d41c96e035 Merge branch 'MOODLE310' 2020-11-18 09:49:19 +01:00
Luuk Verhoeven
29a4857d8a Update for MOODLE310 2020-11-18 09:45:40 +01:00
Luuk Verhoeven
163ee678a5 Update README.md 2020-08-13 19:44:49 +02:00
Luuk Verhoeven
c5a8b00380 Update README.md 2020-08-13 19:25:27 +02:00
Luuk Verhoeven
cc43dbdf0b Merge remote-tracking branch 'origin/master' 2020-06-15 22:17:58 +02:00
Luuk Verhoeven
3ba695cb97 Update for Moodle 3.9 2020-06-15 22:17:50 +02:00
Luuk Verhoeven
020dac34ba Create FUNDING.yml 2020-06-02 21:52:34 +02:00
Luuk Verhoeven
0468b49b6a Update travis tests for Moodle 3.8 2019-11-14 15:53:37 +01:00
Luuk Verhoeven
aba5912e50 Update travis tests for Moodle 3.8 2019-11-14 15:32:38 +01:00
Luuk Verhoeven
fbe446e53b Update travis tests for Moodle 3.8 2019-11-14 15:07:50 +01:00
Luuk Verhoeven
e7e711b67b #2 improve validating ipv6
ipv6 validation regex missing some escaping and strictness
2019-05-22 15:03:00 +02:00
Luuk Verhoeven
1785ee947a Merge remote-tracking branch 'origin/master' 2019-05-22 12:20:42 +02:00
Luuk Verhoeven
86dbd31b2e Add correct builds 2019-05-22 12:20:34 +02:00
Luuk Verhoeven
f1190518b8 Update README.md 2019-05-22 12:18:06 +02:00
Luuk Verhoeven
8eb790f800 #2 improve ip validation
Make sure validate ipv4 address is correct, dont allow additional junk.
2019-05-22 12:14:07 +02:00
Luuk Verhoeven
6c92077941 Add privacy provider. 2019-05-21 14:48:00 +02:00
Luuk Verhoeven
dc0a3aeb43 Update code style 2019-05-15 14:14:14 +02:00
15 changed files with 317 additions and 206 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
github: [MFreakNL]

18
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
# .github/workflows/ci.yml
name: ci
on: [push, pull_request]
jobs:
test:
uses: catalyst/catalyst-moodle-workflows/.github/workflows/ci.yml@main
secrets:
# Required if you plan to publish (uncomment the below)
moodle_org_token: ${{ secrets.MOODLE_ORG_TOKEN }}
with:
# Grunt fails due to CSS styling, when needing an !important statement.
disable_grunt: false
disable_phpunit: true
disable_release : false
release_branches: main
min_php : 7.4

View File

@@ -1,56 +0,0 @@
language: php
# Workaround for fixing that Selenium server is not running and therefore javascript Behat tests are not working:
# https://github.com/moodlerooms/moodle-plugin-ci/issues/70
sudo: required
addons:
firefox: "47.0.1"
postgresql: "9.4"
apt:
packages:
- openjdk-8-jre-headless
cache:
directories:
- $HOME/.composer/cache
- $HOME/.npm
php:
# PHP 5.6 gives errors because of the provider.php needs to be PHP7
- 7.0
- 7.1
env:
global:
- MOODLE_BRANCH=MOODLE_32_STABLE
- MOODLE_BRANCH=MOODLE_35_STABLE
- MOODLE_BRANCH=MOODLE_36_STABLE
matrix:
- DB=pgsql
- DB=mysqli
before_install:
- phpenv config-rm xdebug.ini
- nvm install 8.9
- nvm use 8.9
- cd ../..
- composer create-project -n --no-dev --prefer-dist moodlerooms/moodle-plugin-ci ci ^2
- export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH"
install:
- moodle-plugin-ci add-plugin moodlehq/moodle-local_moodlecheck
- moodle-plugin-ci install
script:
- php moodle/local/moodlecheck/cli/moodlecheck.php --path=availability/condition/ipaddress --format=text
- moodle-plugin-ci phplint
- moodle-plugin-ci phpcpd
- moodle-plugin-ci phpmd
- moodle-plugin-ci codechecker
- moodle-plugin-ci validate
- moodle-plugin-ci savepoints
- moodle-plugin-ci mustache
- moodle-plugin-ci grunt
- moodle-plugin-ci phpunit
- moodle-plugin-ci behat

View File

@@ -1,14 +1,26 @@
## Moodle - availability ip address plugin ## Moodle - availability ip address plugin
Restrict access to any activity by ip-address. Most activities don't support this feature. Enhance activity security by restricting access based on IP address. This plugin allows you to control the availability of any chosen
activity, making it accessible only to users from specified IP addresses.
## Author ## Author
![MFreak.nl](http://MFreak.nl/logo_small.png) ![MFreak.nl](https://MFreak.nl/logo_small.png)
* Author: Luuk Verhoeven, [MFreak.nl](https://MFreak.nl/) * Author: Luuk Verhoeven, [ldesignmedia.nl](https://ldesignmedia.nl/)
* Min. required: Moodle 3.2.x * Min. required: Moodle 4.0
* Supports PHP: 7.0 | 7.1 * Supports PHP: 7.4
[![Build Status](https://travis-ci.org/MFreakNL/moodle-availability_ipaddress.svg?branch=master)](https://travis-ci.org/MFreakNL/moodle-availability_ipaddress) ![Moodle400](https://img.shields.io/badge/moodle-4.0-brightgreen.svg?logo=moodle)
![Moodle401](https://img.shields.io/badge/moodle-4.1-brightgreen.svg?logo=moodle)
![Moodle402](https://img.shields.io/badge/moodle-4.2-brightgreen.svg?logo=moodle)
![Moodle403](https://img.shields.io/badge/moodle-4.3-brightgreen.svg?logo=moodle)
![Moodle404](https://img.shields.io/badge/moodle-4.4-brightgreen.svg?logo=moodle)
![Moodle405](https://img.shields.io/badge/moodle-4.5-brightgreen.svg?logo=moodle)
![Moodle500](https://img.shields.io/badge/moodle-5.0-brightgreen.svg?logo=moodle)
![PHP7.4](https://img.shields.io/badge/PHP-7.4-brightgreen.svg?logo=php)
![PHP8.0](https://img.shields.io/badge/PHP-8.0-brightgreen.svg?logo=php)
![PHP8.1](https://img.shields.io/badge/PHP-8.1-brightgreen.svg?logo=php)
![PHP8.2](https://img.shields.io/badge/PHP-8.2-brightgreen.svg?logo=php)
## List of features ## List of features
- Supports comma separate list of ip-addresses - Supports comma separate list of ip-addresses
@@ -22,9 +34,21 @@ Restrict access to any activity by ip-address. Most activities don't support thi
3. Go to Site Administrator > Notification 3. Go to Site Administrator > Notification
4. Install the plugin 4. Install the plugin
## Usage
1. Add or edit an activity in a Moodle course.
2. Go to the section "Restrict access"
3. Click IP address in the modal
4. There's a new input field that supports a list of comma separated ip address e.g. 127.0.0.1, 192.168.1.0/24
1. The users with matching ip addresses can view the activity.
5. Save the activity
## TODO
- Behat tests ip validation
## Security ## Security
If you discover any security related issues, please email [luuk@MFreak.nl](mailto:luuk@MFreak.nl) instead of using the issue tracker. If you discover any security related issues, please email [luuk@ldesignmedia.nl](mailto:luuk@ldesignmedia.nl) instead of using the issue tracker.
## License ## License
@@ -33,3 +57,11 @@ The GNU GENERAL PUBLIC LICENSE. Please see [License File](LICENSE) for more info
## Contributing ## Contributing
Contributions are welcome and will be fully credited. We accept contributions via Pull Requests on Github. Contributions are welcome and will be fully credited. We accept contributions via Pull Requests on Github.
## Changelog
- 2025040400 Tested on Moodle 4.5
- 2024072000 Tested on Moodle 4.4
- 2022021100 Thanks for adding ip-range support @[juacas](https://github.com/juacas)
- 2022052800 Fixed the [issue 6](https://github.com/ldesignmediaNL/moodle-availability_ipaddress/issues/6) @[hamzatamyachte](https://github.com/hamzatamyachte)
- 2022052801 Test in Moodle 4.0 @[hamzatamyachte](https://github.com/hamzatamyachte)

View File

@@ -28,8 +28,6 @@ namespace availability_ipaddress;
use core_availability\info; use core_availability\info;
defined('MOODLE_INTERNAL') || die;
/** /**
* Class condition * Class condition
* *
@@ -42,7 +40,7 @@ class condition extends \core_availability\condition {
/** /**
* @var string * @var string
*/ */
protected $ipaddresses = ''; protected string $ipaddresses = '';
/** /**
* condition constructor. * condition constructor.
@@ -75,22 +73,22 @@ class condition extends \core_availability\condition {
* @param bool $grabthelot Performance hint: if true, caches information * @param bool $grabthelot Performance hint: if true, caches information
* required for all course-modules, to make the front page and similar * required for all course-modules, to make the front page and similar
* pages work more quickly (works only for current user) * pages work more quickly (works only for current user)
* @param int $userid User ID to check availability for * @param int $userid User ID to check availability for
* *
* @return bool True if available * @return bool True if available
*/ */
public function is_available($not, info $info, $grabthelot, $userid) { public function is_available($not, info $info, $grabthelot, $userid): bool {
if (empty($this->ipaddresses)) { if (empty($this->ipaddresses)) {
return true; return !$not;
} }
// Check if ip-address matches. // Check if ip-address matches.
if (address_in_subnet(getremoteaddr(), trim($this->ipaddresses))) { if (address_in_subnet(getremoteaddr(), trim($this->ipaddresses))) {
return true; return !$not;
} }
return false; return $not;
} }
/** /**
@@ -114,12 +112,10 @@ class condition extends \core_availability\condition {
* @param bool $not Set true if we are inverting the condition * @param bool $not Set true if we are inverting the condition
* @param info $info Item we're checking * @param info $info Item we're checking
* *
* @return string Information string (for admin) about all restrictions on * @return string Information string (for admin) about all restrictions on this item
* this item
* @throws \coding_exception
*/ */
public function get_description($full, $not, info $info) { public function get_description($full, $not, info $info): string {
return get_string('require_condition', 'availability_ipaddress'); return get_string('require_condition', 'availability_ipaddress', getremoteaddr());
} }
/** /**
@@ -128,7 +124,7 @@ class condition extends \core_availability\condition {
* *
* @return string Text representation of parameters * @return string Text representation of parameters
*/ */
protected function get_debug_string() { protected function get_debug_string(): string {
return !empty($this->ipaddresses) ? 'ipaddresses ON' : 'ipaddresses OFF'; return !empty($this->ipaddresses) ? 'ipaddresses ON' : 'ipaddresses OFF';
} }
@@ -142,41 +138,23 @@ class condition extends \core_availability\condition {
* *
* @return \stdClass Object representing condition * @return \stdClass Object representing condition
*/ */
public static function get_json($ipaddresses) { public static function get_json(string $ipaddresses): \stdClass {
return (object)[ return (object) [
'type' => 'ipaddress', 'type' => 'ipaddress',
'ipaddresses' => $ipaddresses, 'ipaddresses' => $ipaddresses,
]; ];
} }
/**
* Check if ip-address is valid
*
* @param string $ipaddresses
*
* @return bool
*/
public static function is_valid_ipaddresses($ipaddresses) {
$ipaddresses = implode(',', $ipaddresses);
foreach ($ipaddresses as $ipaddress) {
if (!filter_var($ipaddress, FILTER_VALIDATE_IP)) {
return false;
}
}
return true;
}
/** /**
* Saves tree data back to a structure object. * Saves tree data back to a structure object.
* *
* @return \stdClass Structure object (ready to be made into JSON format) * @return \stdClass Structure object (ready to be made into JSON format)
*/ */
public function save() { public function save(): \stdClass {
return (object)[ return (object) [
'type' => 'ipaddress', 'type' => 'ipaddress',
'ipaddresses' => $this->ipaddresses, 'ipaddresses' => $this->ipaddresses,
]; ];
} }
}
}

View File

@@ -25,7 +25,6 @@
**/ **/
namespace availability_ipaddress; namespace availability_ipaddress;
defined('MOODLE_INTERNAL') || die;
/** /**
* Class frontend * Class frontend
@@ -41,24 +40,11 @@ class frontend extends \core_availability\frontend {
* *
* @return array * @return array
*/ */
protected function get_javascript_strings() { protected function get_javascript_strings(): array {
return [ return [
'js:ipaddress', 'js:ipaddress',
'error_ipaddress', 'error_ipaddress',
]; ];
} }
/** }
* Decides whether this plugin should be available in a given course. The
* plugin can do this depending on course or system settings.
*
* @param \stdClass $course Course object
* @param \cm_info $cm Course-module currently being edited (null if none)
* @param \section_info $section Section currently being edited (null if none)
*
* @return bool True if there are completion criteria
*/
protected function allow_add($course, \cm_info $cm = null, \section_info $section = null) {
return true;
}
}

View File

@@ -0,0 +1,47 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for availability_ipaddress.
*
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @package availability_ipaddress
* @copyright 2019-05-14 Mfreak.nl | LdesignMedia.nl - Luuk Verhoeven
* @author Luuk Verhoeven
**/
namespace availability_ipaddress\privacy;
/**
* Privacy Subsystem for availability_ipaddress implementing null_provider.
*
* @copyright 2019-05-14 Mfreak.nl | LdesignMedia.nl - Luuk Verhoeven
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}

6
environment.xml Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<COMPATIBILITY_MATRIX>
<PLUGIN name="availability_ipaddress">
<PHP version="7.4" level="required"/>
</PLUGIN>
</COMPATIBILITY_MATRIX>

View File

@@ -23,13 +23,17 @@
* @copyright 2019-05-14 Mfreak.nl | LdesignMedia.nl - Luuk Verhoeven * @copyright 2019-05-14 Mfreak.nl | LdesignMedia.nl - Luuk Verhoeven
* @author Luuk Verhoeven * @author Luuk Verhoeven
**/ **/
$string['pluginname'] = 'IP address'; $string['pluginname'] = 'IP address';
$string['title'] = 'IP address';
$string['description'] = 'Restrict access by ip-address or subnet'; $string['description'] = 'Restrict access by ip-address or subnet';
$string['require_condition'] = 'Matching ip-address/subnet'; $string['title'] = 'IP address';
$string['require_condition'] = 'Matching ip-address/subnet. (Your IP:{$a})';
// Errors.
$string['error_ipaddress'] = 'Incorrect ip-address/subnet format';
// Javascript strings. // Javascript strings.
$string['js:ipaddress'] = 'Require network address'; $string['js:ipaddress'] = 'Require network address';
// Errors. // Privacy provider.
$string['error_ipaddress'] = 'Incorrect ip-address/subnet format'; $string['privacy:metadata'] = 'The restriction by activity ipaddress plugin does not store any personal data.';

View File

@@ -27,7 +27,8 @@
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
$plugin->component = 'availability_ipaddress'; $plugin->component = 'availability_ipaddress';
$plugin->version = 2019051500; $plugin->version = 2025052100;
$plugin->release = 'v3.5.0'; $plugin->release = '5.0.0';
$plugin->requires = 2016120500; $plugin->requires = 2016120500;
$plugin->maturity = MATURITY_BETA; $plugin->maturity = MATURITY_STABLE;
$plugin->supported = [400, 500];

View File

@@ -19,19 +19,17 @@ M.availability_ipaddress = M.availability_ipaddress || {};
// Advanced ip-address regex for validating. // Advanced ip-address regex for validating.
M.availability_ipaddress.v4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]' + M.availability_ipaddress.v4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]' +
'[0-9]|[1-9][0-9]|[0-9])){3}'; '[0-9]|[1-9][0-9]|[0-9])){3}';
M.availability_ipaddress.v6 = '((?:[0-9a-fA-F]{1,4}:){7}(?:[0-9a-fA-F]{1,4}|:)|(?:[0-9a-fA-F]{1,4}:){6}(?:(?:25[0-5]|2[0-4]' + M.availability_ipaddress.v6 = "^((?:[a-fA-F\\d]{1,4}:){7}(?:[a-fA-F\\d]{1,4}|:)|(?:[a-fA-F\\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]" +
'[0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|:[0-9a-fA-F]{1,4}|:)' + "\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|:[a-fA-F\\d]{1,4}|:)|(?:[a-fA-F\\d]{1,4}:){5}" +
'|(?:[0-9a-fA-F]{1,4}:){5}(?::(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]' + "(?::(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4})" +
'|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,2}|:)|(?:[0-9a-fA-F]{1,4}:){4}(?:' + "{1,2}|:)|(?:[a-fA-F\\d]{1,4}:){4}(?:(:[a-fA-F\\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]" +
'(:[0-9a-fA-F]{1,4}){0,1}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]' + "|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,3}|:)|(?:[a-fA-F\\d]{1,4}:){3}(?:(:[a-fA-F\\d]{1,4}){0,2}:" +
'|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,3}|:)|(?:[0-9a-fA-F]{1,4}:){3}(?:(:[0-9a-fA-F]{1,4}){0,2}:(?:25[0-5]|2[0-4]' + "(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,4}|:)|" +
'[0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|' + "(?:[a-fA-F\\d]{1,4}:){2}(?:(:[a-fA-F\\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]" +
'(:[0-9a-fA-F]{1,4}){1,4}|:)|(?:[0-9a-fA-F]{1,4}:){2}(?:(:[0-9a-fA-F]{1,4}){0,3}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|' + "\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,5}|:)|(?:[a-fA-F\\d]{1,4}:){1}(?:(:[a-fA-F\\d]{1,4}){0,4}:(?:25[0-5]" +
'[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,5}|:)|' + "|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,6}|:)|(?::" +
'(?:[0-9a-fA-F]{1,4}:){1}(?:(:[0-9a-fA-F]{1,4}){0,4}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.' + "((?::[a-fA-F\\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}" +
'(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,6}|:)|(?::((?::[0-9a-fA-F]{1,4}){0,5}' + "|(?::[a-fA-F\\d]{1,4}){1,7}|:)))(%[0-9a-zA-Z]{1,})?";
':(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|' +
'(?::[0-9a-fA-F]{1,4}){1,7}|:)))(%[0-9a-zA-Z]{1,})?';
/** /**
* @class M.availability_ipaddress.form * @class M.availability_ipaddress.form
@@ -47,7 +45,7 @@ M.availability_ipaddress.form = Y.Object(M.core_availability.plugin);
*/ */
M.availability_ipaddress.form.initInner = function() { M.availability_ipaddress.form.initInner = function() {
"use strict"; "use strict";
Y.log('M.availability_ipaddress'); Y.log('M.availability_ipaddress 1.10');
}; };
/** /**
@@ -55,27 +53,29 @@ M.availability_ipaddress.form.initInner = function() {
* dot or comma). * dot or comma).
* *
* @method getValue * @method getValue
* @param {string} field
* @param {object} node
* @return {Number|String} Value of field as number or string if not valid * @return {Number|String} Value of field as number or string if not valid
*/ */
M.availability_ipaddress.form.getValue = function(field, node) { M.availability_ipaddress.form.getValue = function(field, node) {
"use strict"; "use strict";
// Get field value. // Get field value.
var value = node.one('input[name=' + field + ']').get('value'); var value = node.one('input[name=' + field + ']').get('value');
Y.log('ip_address:', value); Y.log('ip_address:' + value);
// If it is not a valid positive number, return false. // If it is not a valid positive number, return false.
if (M.availability_ipaddress.validate_ipaddress(value)) { if (M.availability_ipaddress.validateIpaddress(value)) {
Y.log('Valid ip-address'); Y.log('Valid ip-address');
return value; return value;
} }
Y.log('getValue failed:', value);
return value; return value;
}; };
/** /**
* getNode * Get node
* @param json *
* @param {object} json
* @returns {*} * @returns {*}
*/ */
M.availability_ipaddress.form.getNode = function(json) { M.availability_ipaddress.form.getNode = function(json) {
@@ -112,38 +112,65 @@ M.availability_ipaddress.form.getNode = function(json) {
}; };
/** /**
* validate_ipaddress * Validate ipaddresses
* *
* @param {string[]} ipaddresses * @param {string[]} ipaddresses
* @returns {boolean} * @returns {boolean}
*/ */
M.availability_ipaddress.validate_ipaddress = function(ipaddresses) { M.availability_ipaddress.validateIpaddress = function(ipaddresses) {
'use strict'; 'use strict';
Y.log(ipaddresses);
ipaddresses = ipaddresses.split(','); ipaddresses = ipaddresses.split(',');
for (var i in ipaddresses) { for (var i in ipaddresses) {
// Test normal ip format. // Test normal ip format.
if (new RegExp("(?:".concat(M.availability_ipaddress.v4, ")|(?:").concat(M.availability_ipaddress.v6, ")"), "g") // Strict ipv4 check.
if (new RegExp(/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/gm)
.test(ipaddresses[i])) { .test(ipaddresses[i])) {
Y.log('Correct ipv4');
continue;
}
var ipv4Regex = new RegExp(
'^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)' +
'(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}-' +
'([0-1]?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5]){1}$',
'gm'
);
if (ipv4Regex.test(ipaddresses[i])) {
Y.log('Correct ipv4 range.');
continue;
}
if (new RegExp(M.availability_ipaddress.v6)
.test(ipaddresses[i])) {
Y.log('Correct ipv6');
continue; continue;
} }
// Test subnet with a regex. // Test subnet with a regex.
if (new RegExp("(?:".concat(M.availability_ipaddress.v4 + "\\/(3[0-2]|[12]?[0-9])", ")|(?:") if (new RegExp("^(?:".concat(M.availability_ipaddress.v4 + "\\/(3[0-2]|[12]?[0-9])|(1\\*)", ")|(?:")
.concat(M.availability_ipaddress.v6 + "\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])", ")"), "g") .concat(M.availability_ipaddress.v6 + "\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])", ")?\\/gm"))
.test(ipaddresses[i])) { .test(ipaddresses[i])) {
Y.log('Correct subnet');
continue; continue;
} }
Y.log('Incorrect ip', ipaddresses[i]); Y.log('Incorrect ip');
return false; return false;
} }
Y.log('Valid ipaddresses', ipaddresses); Y.log('Valid ipaddresses');
return true; return true;
}; };
/**
* FillValue
*
* @param {object} value
* @param {object} node
*/
M.availability_ipaddress.form.fillValue = function(value, node) { M.availability_ipaddress.form.fillValue = function(value, node) {
// This function gets passed the node (from above) and a value // This function gets passed the node (from above) and a value
// object. Within that object, it must set up the correct values // object. Within that object, it must set up the correct values
@@ -153,15 +180,21 @@ M.availability_ipaddress.form.fillValue = function(value, node) {
value.ipaddresses = this.getValue('ipaddresses', node); value.ipaddresses = this.getValue('ipaddresses', node);
}; };
/**
* FillErrors
* @param {object} errors
* @param {object} node
*/
M.availability_ipaddress.form.fillErrors = function(errors, node) { M.availability_ipaddress.form.fillErrors = function(errors, node) {
"use strict"; "use strict";
var value = {}; var value = {};
this.fillValue(value, node); this.fillValue(value, node);
// Basic ipaddresses checks. // Basic ipaddresses checks.
if (M.availability_ipaddress.validate_ipaddress(value.ipaddresses) === false) { if (M.availability_ipaddress.validateIpaddress(value.ipaddresses) === false) {
errors.push('availability_ipaddress:error_ipaddress'); errors.push('availability_ipaddress:error_ipaddress');
} }
}; };
}, '@VERSION@', {"requires": ["base", "node", "event", "moodle-core_availability-form"]}); }, '@VERSION@', {"requires": ["base", "node", "event", "moodle-core_availability-form"]});

View File

@@ -1 +1 @@
YUI.add("moodle-availability_ipaddress-form",function(e,t){M.availability_ipaddress=M.availability_ipaddress||{},M.availability_ipaddress.v4="(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}",M.availability_ipaddress.v6="((?:[0-9a-fA-F]{1,4}:){7}(?:[0-9a-fA-F]{1,4}|:)|(?:[0-9a-fA-F]{1,4}:){6}(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|:[0-9a-fA-F]{1,4}|:)|(?:[0-9a-fA-F]{1,4}:){5}(?::(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,2}|:)|(?:[0-9a-fA-F]{1,4}:){4}(?:(:[0-9a-fA-F]{1,4}){0,1}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,3}|:)|(?:[0-9a-fA-F]{1,4}:){3}(?:(:[0-9a-fA-F]{1,4}){0,2}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,4}|:)|(?:[0-9a-fA-F]{1,4}:){2}(?:(:[0-9a-fA-F]{1,4}){0,3}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,5}|:)|(?:[0-9a-fA-F]{1,4}:){1}(?:(:[0-9a-fA-F]{1,4}){0,4}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,6}|:)|(?::((?::[0-9a-fA-F]{1,4}){0,5}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(?::[0-9a-fA-F]{1,4}){1,7}|:)))(%[0-9a-zA-Z]{1,})?",M.availability_ipaddress.form=e.Object(M.core_availability.plugin),M.availability_ipaddress.form.initInner=function(){"use strict";},M.availability_ipaddress.form.getValue=function(e,t){"use strict";var n=t.one("input[name="+e+"]").get("value");return M.availability_ipaddress.validate_ipaddress(n)?n:n},M.availability_ipaddress.form.getNode=function(t){"use strict";var n,r,i,s;return s="ipaddresses"+M.availability_ipaddress.form.instId,M.availability_ipaddress.form.instId+=1,n="",n+='<span class="availability-group"><label for="'+s+'"><span class="p-r-1">'+M.util.get_string("title","availability_ipaddress")+" </span></label>",n+='<input type="text" placeholder="192.168.178.1,231.54.211.0/20,231.3.56.211" name="ipaddresses" id="'+s+'">',r=e.Node.create('<span class="form-inline">'+n+"</span>"),t.ipaddresses!==undefined&&r.one("input[name=ipaddresses]").set("value",t.ipaddresses),M.availability_ipaddress.form.addedEvents||(M.availability_ipaddress.form.addedEvents=!0,i=e.one(".availability-field"),i.delegate("valuechange",function(){M.core_availability.form.update()},".availability_ipaddress input[name=ipaddresses]")),r},M.availability_ipaddress.validate_ipaddress=function(e){"use strict";e=e.split(",");for(var t in e){if((new RegExp("(?:".concat(M.availability_ipaddress.v4,")|(?:").concat(M.availability_ipaddress.v6,")"),"g")).test(e[t]))continue;if((new RegExp("(?:".concat(M.availability_ipaddress.v4+"\\/(3[0-2]|[12]?[0-9])",")|(?:").concat(M.availability_ipaddress.v6+"\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])",")"),"g")).test(e[t]))continue;return!1}return!0},M.availability_ipaddress.form.fillValue=function(e,t){e.ipaddresses=this.getValue("ipaddresses",t)},M.availability_ipaddress.form.fillErrors=function(e,t){"use strict";var n={};this.fillValue(n,t),M.availability_ipaddress.validate_ipaddress(n.ipaddresses)===!1&&e.push("availability_ipaddress:error_ipaddress")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]}); YUI.add("moodle-availability_ipaddress-form",function(e,d){M.availability_ipaddress=M.availability_ipaddress||{},M.availability_ipaddress.v4="(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}",M.availability_ipaddress.v6="^((?:[a-fA-F\\d]{1,4}:){7}(?:[a-fA-F\\d]{1,4}|:)|(?:[a-fA-F\\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|:[a-fA-F\\d]{1,4}|:)|(?:[a-fA-F\\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,2}|:)|(?:[a-fA-F\\d]{1,4}:){4}(?:(:[a-fA-F\\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,3}|:)|(?:[a-fA-F\\d]{1,4}:){3}(?:(:[a-fA-F\\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,4}|:)|(?:[a-fA-F\\d]{1,4}:){2}(?:(:[a-fA-F\\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,5}|:)|(?:[a-fA-F\\d]{1,4}:){1}(?:(:[a-fA-F\\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,6}|:)|(?::((?::[a-fA-F\\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?::[a-fA-F\\d]{1,4}){1,7}|:)))(%[0-9a-zA-Z]{1,})?",M.availability_ipaddress.form=e.Object(M.core_availability.plugin),M.availability_ipaddress.form.initInner=function(){},M.availability_ipaddress.form.getValue=function(d,a){"use strict";d=a.one("input[name="+d+"]").get("value");return M.availability_ipaddress.validateIpaddress(d),d},M.availability_ipaddress.form.getNode=function(d){"use strict";var a,i="ipaddresses"+M.availability_ipaddress.form.instId;return M.availability_ipaddress.form.instId+=1,a="",a+='<span class="availability-group"><label for="'+i+'"><span class="p-r-1">'+M.util.get_string("title","availability_ipaddress")+" </span></label>",i=e.Node.create('<span class="form-inline">'+(a+='<input type="text" placeholder="192.168.178.1,231.54.211.0/20,231.3.56.211" name="ipaddresses" id="'+i+'">')+"</span>"),d.ipaddresses!==undefined&&i.one("input[name=ipaddresses]").set("value",d.ipaddresses),M.availability_ipaddress.form.addedEvents||(M.availability_ipaddress.form.addedEvents=!0,e.one(".availability-field").delegate("valuechange",function(){M.core_availability.form.update()},".availability_ipaddress input[name=ipaddresses]")),i},M.availability_ipaddress.validateIpaddress=function(d){"use strict";for(var a in d=d.split(","))if(!(new RegExp(/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/gm).test(d[a])||new RegExp("^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}-([0-1]?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5]){1}$","gm").test(d[a])||new RegExp(M.availability_ipaddress.v6).test(d[a])||new RegExp("^(?:".concat(M.availability_ipaddress.v4+"\\/(3[0-2]|[12]?[0-9])|(1\\*)",")|(?:").concat(M.availability_ipaddress.v6+"\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])",")?\\/gm")).test(d[a])))return!1;return!0},M.availability_ipaddress.form.fillValue=function(d,a){d.ipaddresses=this.getValue("ipaddresses",a)},M.availability_ipaddress.form.fillErrors=function(d,a){"use strict";var i={};this.fillValue(i,a),!1===M.availability_ipaddress.validateIpaddress(i.ipaddresses)&&d.push("availability_ipaddress:error_ipaddress")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});

View File

@@ -19,19 +19,17 @@ M.availability_ipaddress = M.availability_ipaddress || {};
// Advanced ip-address regex for validating. // Advanced ip-address regex for validating.
M.availability_ipaddress.v4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]' + M.availability_ipaddress.v4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]' +
'[0-9]|[1-9][0-9]|[0-9])){3}'; '[0-9]|[1-9][0-9]|[0-9])){3}';
M.availability_ipaddress.v6 = '((?:[0-9a-fA-F]{1,4}:){7}(?:[0-9a-fA-F]{1,4}|:)|(?:[0-9a-fA-F]{1,4}:){6}(?:(?:25[0-5]|2[0-4]' + M.availability_ipaddress.v6 = "^((?:[a-fA-F\\d]{1,4}:){7}(?:[a-fA-F\\d]{1,4}|:)|(?:[a-fA-F\\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]" +
'[0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|:[0-9a-fA-F]{1,4}|:)' + "\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|:[a-fA-F\\d]{1,4}|:)|(?:[a-fA-F\\d]{1,4}:){5}" +
'|(?:[0-9a-fA-F]{1,4}:){5}(?::(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]' + "(?::(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4})" +
'|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,2}|:)|(?:[0-9a-fA-F]{1,4}:){4}(?:' + "{1,2}|:)|(?:[a-fA-F\\d]{1,4}:){4}(?:(:[a-fA-F\\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]" +
'(:[0-9a-fA-F]{1,4}){0,1}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]' + "|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,3}|:)|(?:[a-fA-F\\d]{1,4}:){3}(?:(:[a-fA-F\\d]{1,4}){0,2}:" +
'|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,3}|:)|(?:[0-9a-fA-F]{1,4}:){3}(?:(:[0-9a-fA-F]{1,4}){0,2}:(?:25[0-5]|2[0-4]' + "(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,4}|:)|" +
'[0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|' + "(?:[a-fA-F\\d]{1,4}:){2}(?:(:[a-fA-F\\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]" +
'(:[0-9a-fA-F]{1,4}){1,4}|:)|(?:[0-9a-fA-F]{1,4}:){2}(?:(:[0-9a-fA-F]{1,4}){0,3}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|' + "\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,5}|:)|(?:[a-fA-F\\d]{1,4}:){1}(?:(:[a-fA-F\\d]{1,4}){0,4}:(?:25[0-5]" +
'[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,5}|:)|' + "|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,6}|:)|(?::" +
'(?:[0-9a-fA-F]{1,4}:){1}(?:(:[0-9a-fA-F]{1,4}){0,4}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.' + "((?::[a-fA-F\\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}" +
'(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,6}|:)|(?::((?::[0-9a-fA-F]{1,4}){0,5}' + "|(?::[a-fA-F\\d]{1,4}){1,7}|:)))(%[0-9a-zA-Z]{1,})?";
':(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|' +
'(?::[0-9a-fA-F]{1,4}){1,7}|:)))(%[0-9a-zA-Z]{1,})?';
/** /**
* @class M.availability_ipaddress.form * @class M.availability_ipaddress.form
@@ -54,6 +52,8 @@ M.availability_ipaddress.form.initInner = function() {
* dot or comma). * dot or comma).
* *
* @method getValue * @method getValue
* @param {string} field
* @param {object} node
* @return {Number|String} Value of field as number or string if not valid * @return {Number|String} Value of field as number or string if not valid
*/ */
M.availability_ipaddress.form.getValue = function(field, node) { M.availability_ipaddress.form.getValue = function(field, node) {
@@ -62,7 +62,7 @@ M.availability_ipaddress.form.getValue = function(field, node) {
var value = node.one('input[name=' + field + ']').get('value'); var value = node.one('input[name=' + field + ']').get('value');
// If it is not a valid positive number, return false. // If it is not a valid positive number, return false.
if (M.availability_ipaddress.validate_ipaddress(value)) { if (M.availability_ipaddress.validateIpaddress(value)) {
return value; return value;
} }
@@ -70,8 +70,9 @@ M.availability_ipaddress.form.getValue = function(field, node) {
}; };
/** /**
* getNode * Get node
* @param json *
* @param {object} json
* @returns {*} * @returns {*}
*/ */
M.availability_ipaddress.form.getNode = function(json) { M.availability_ipaddress.form.getNode = function(json) {
@@ -108,26 +109,42 @@ M.availability_ipaddress.form.getNode = function(json) {
}; };
/** /**
* validate_ipaddress * Validate ipaddresses
* *
* @param {string[]} ipaddresses * @param {string[]} ipaddresses
* @returns {boolean} * @returns {boolean}
*/ */
M.availability_ipaddress.validate_ipaddress = function(ipaddresses) { M.availability_ipaddress.validateIpaddress = function(ipaddresses) {
'use strict'; 'use strict';
ipaddresses = ipaddresses.split(','); ipaddresses = ipaddresses.split(',');
for (var i in ipaddresses) { for (var i in ipaddresses) {
// Test normal ip format. // Test normal ip format.
if (new RegExp("(?:".concat(M.availability_ipaddress.v4, ")|(?:").concat(M.availability_ipaddress.v6, ")"), "g") // Strict ipv4 check.
if (new RegExp(/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/gm)
.test(ipaddresses[i])) {
continue;
}
var ipv4Regex = new RegExp(
'^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)' +
'(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}-' +
'([0-1]?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5]){1}$',
'gm'
);
if (ipv4Regex.test(ipaddresses[i])) {
continue;
}
if (new RegExp(M.availability_ipaddress.v6)
.test(ipaddresses[i])) { .test(ipaddresses[i])) {
continue; continue;
} }
// Test subnet with a regex. // Test subnet with a regex.
if (new RegExp("(?:".concat(M.availability_ipaddress.v4 + "\\/(3[0-2]|[12]?[0-9])", ")|(?:") if (new RegExp("^(?:".concat(M.availability_ipaddress.v4 + "\\/(3[0-2]|[12]?[0-9])|(1\\*)", ")|(?:")
.concat(M.availability_ipaddress.v6 + "\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])", ")"), "g") .concat(M.availability_ipaddress.v6 + "\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])", ")?\\/gm"))
.test(ipaddresses[i])) { .test(ipaddresses[i])) {
continue; continue;
} }
@@ -138,6 +155,12 @@ M.availability_ipaddress.validate_ipaddress = function(ipaddresses) {
return true; return true;
}; };
/**
* FillValue
*
* @param {object} value
* @param {object} node
*/
M.availability_ipaddress.form.fillValue = function(value, node) { M.availability_ipaddress.form.fillValue = function(value, node) {
// This function gets passed the node (from above) and a value // This function gets passed the node (from above) and a value
// object. Within that object, it must set up the correct values // object. Within that object, it must set up the correct values
@@ -147,15 +170,21 @@ M.availability_ipaddress.form.fillValue = function(value, node) {
value.ipaddresses = this.getValue('ipaddresses', node); value.ipaddresses = this.getValue('ipaddresses', node);
}; };
/**
* FillErrors
* @param {object} errors
* @param {object} node
*/
M.availability_ipaddress.form.fillErrors = function(errors, node) { M.availability_ipaddress.form.fillErrors = function(errors, node) {
"use strict"; "use strict";
var value = {}; var value = {};
this.fillValue(value, node); this.fillValue(value, node);
// Basic ipaddresses checks. // Basic ipaddresses checks.
if (M.availability_ipaddress.validate_ipaddress(value.ipaddresses) === false) { if (M.availability_ipaddress.validateIpaddress(value.ipaddresses) === false) {
errors.push('availability_ipaddress:error_ipaddress'); errors.push('availability_ipaddress:error_ipaddress');
} }
}; };
}, '@VERSION@', {"requires": ["base", "node", "event", "moodle-core_availability-form"]}); }, '@VERSION@', {"requires": ["base", "node", "event", "moodle-core_availability-form"]});

View File

@@ -17,19 +17,17 @@ M.availability_ipaddress = M.availability_ipaddress || {};
// Advanced ip-address regex for validating. // Advanced ip-address regex for validating.
M.availability_ipaddress.v4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]' + M.availability_ipaddress.v4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9]' +
'[0-9]|[1-9][0-9]|[0-9])){3}'; '[0-9]|[1-9][0-9]|[0-9])){3}';
M.availability_ipaddress.v6 = '((?:[0-9a-fA-F]{1,4}:){7}(?:[0-9a-fA-F]{1,4}|:)|(?:[0-9a-fA-F]{1,4}:){6}(?:(?:25[0-5]|2[0-4]' + M.availability_ipaddress.v6 = "^((?:[a-fA-F\\d]{1,4}:){7}(?:[a-fA-F\\d]{1,4}|:)|(?:[a-fA-F\\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]" +
'[0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|:[0-9a-fA-F]{1,4}|:)' + "\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|:[a-fA-F\\d]{1,4}|:)|(?:[a-fA-F\\d]{1,4}:){5}" +
'|(?:[0-9a-fA-F]{1,4}:){5}(?::(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]' + "(?::(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4})" +
'|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,2}|:)|(?:[0-9a-fA-F]{1,4}:){4}(?:' + "{1,2}|:)|(?:[a-fA-F\\d]{1,4}:){4}(?:(:[a-fA-F\\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]" +
'(:[0-9a-fA-F]{1,4}){0,1}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]' + "|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,3}|:)|(?:[a-fA-F\\d]{1,4}:){3}(?:(:[a-fA-F\\d]{1,4}){0,2}:" +
'|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,3}|:)|(?:[0-9a-fA-F]{1,4}:){3}(?:(:[0-9a-fA-F]{1,4}){0,2}:(?:25[0-5]|2[0-4]' + "(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,4}|:)|" +
'[0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|' + "(?:[a-fA-F\\d]{1,4}:){2}(?:(:[a-fA-F\\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]" +
'(:[0-9a-fA-F]{1,4}){1,4}|:)|(?:[0-9a-fA-F]{1,4}:){2}(?:(:[0-9a-fA-F]{1,4}){0,3}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|' + "\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,5}|:)|(?:[a-fA-F\\d]{1,4}:){1}(?:(:[a-fA-F\\d]{1,4}){0,4}:(?:25[0-5]" +
'[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,5}|:)|' + "|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(:[a-fA-F\\d]{1,4}){1,6}|:)|(?::" +
'(?:[0-9a-fA-F]{1,4}:){1}(?:(:[0-9a-fA-F]{1,4}){0,4}:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.' + "((?::[a-fA-F\\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}" +
'(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(:[0-9a-fA-F]{1,4}){1,6}|:)|(?::((?::[0-9a-fA-F]{1,4}){0,5}' + "|(?::[a-fA-F\\d]{1,4}){1,7}|:)))(%[0-9a-zA-Z]{1,})?";
':(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|' +
'(?::[0-9a-fA-F]{1,4}){1,7}|:)))(%[0-9a-zA-Z]{1,})?';
/** /**
* @class M.availability_ipaddress.form * @class M.availability_ipaddress.form
@@ -45,7 +43,7 @@ M.availability_ipaddress.form = Y.Object(M.core_availability.plugin);
*/ */
M.availability_ipaddress.form.initInner = function() { M.availability_ipaddress.form.initInner = function() {
"use strict"; "use strict";
Y.log('M.availability_ipaddress'); Y.log('M.availability_ipaddress 1.10');
}; };
/** /**
@@ -53,27 +51,29 @@ M.availability_ipaddress.form.initInner = function() {
* dot or comma). * dot or comma).
* *
* @method getValue * @method getValue
* @param {string} field
* @param {object} node
* @return {Number|String} Value of field as number or string if not valid * @return {Number|String} Value of field as number or string if not valid
*/ */
M.availability_ipaddress.form.getValue = function(field, node) { M.availability_ipaddress.form.getValue = function(field, node) {
"use strict"; "use strict";
// Get field value. // Get field value.
var value = node.one('input[name=' + field + ']').get('value'); var value = node.one('input[name=' + field + ']').get('value');
Y.log('ip_address:', value); Y.log('ip_address:' + value);
// If it is not a valid positive number, return false. // If it is not a valid positive number, return false.
if (M.availability_ipaddress.validate_ipaddress(value)) { if (M.availability_ipaddress.validateIpaddress(value)) {
Y.log('Valid ip-address'); Y.log('Valid ip-address');
return value; return value;
} }
Y.log('getValue failed:', value);
return value; return value;
}; };
/** /**
* getNode * Get node
* @param json *
* @param {object} json
* @returns {*} * @returns {*}
*/ */
M.availability_ipaddress.form.getNode = function(json) { M.availability_ipaddress.form.getNode = function(json) {
@@ -110,38 +110,65 @@ M.availability_ipaddress.form.getNode = function(json) {
}; };
/** /**
* validate_ipaddress * Validate ipaddresses
* *
* @param {string[]} ipaddresses * @param {string[]} ipaddresses
* @returns {boolean} * @returns {boolean}
*/ */
M.availability_ipaddress.validate_ipaddress = function(ipaddresses) { M.availability_ipaddress.validateIpaddress = function(ipaddresses) {
'use strict'; 'use strict';
Y.log(ipaddresses);
ipaddresses = ipaddresses.split(','); ipaddresses = ipaddresses.split(',');
for (var i in ipaddresses) { for (var i in ipaddresses) {
// Test normal ip format. // Test normal ip format.
if (new RegExp("(?:".concat(M.availability_ipaddress.v4, ")|(?:").concat(M.availability_ipaddress.v6, ")"), "g") // Strict ipv4 check.
if (new RegExp(/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/gm)
.test(ipaddresses[i])) { .test(ipaddresses[i])) {
Y.log('Correct ipv4');
continue;
}
var ipv4Regex = new RegExp(
'^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)' +
'(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}-' +
'([0-1]?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5]){1}$',
'gm'
);
if (ipv4Regex.test(ipaddresses[i])) {
Y.log('Correct ipv4 range.');
continue;
}
if (new RegExp(M.availability_ipaddress.v6)
.test(ipaddresses[i])) {
Y.log('Correct ipv6');
continue; continue;
} }
// Test subnet with a regex. // Test subnet with a regex.
if (new RegExp("(?:".concat(M.availability_ipaddress.v4 + "\\/(3[0-2]|[12]?[0-9])", ")|(?:") if (new RegExp("^(?:".concat(M.availability_ipaddress.v4 + "\\/(3[0-2]|[12]?[0-9])|(1\\*)", ")|(?:")
.concat(M.availability_ipaddress.v6 + "\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])", ")"), "g") .concat(M.availability_ipaddress.v6 + "\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])", ")?\\/gm"))
.test(ipaddresses[i])) { .test(ipaddresses[i])) {
Y.log('Correct subnet');
continue; continue;
} }
Y.log('Incorrect ip', ipaddresses[i]); Y.log('Incorrect ip');
return false; return false;
} }
Y.log('Valid ipaddresses', ipaddresses); Y.log('Valid ipaddresses');
return true; return true;
}; };
/**
* FillValue
*
* @param {object} value
* @param {object} node
*/
M.availability_ipaddress.form.fillValue = function(value, node) { M.availability_ipaddress.form.fillValue = function(value, node) {
// This function gets passed the node (from above) and a value // This function gets passed the node (from above) and a value
// object. Within that object, it must set up the correct values // object. Within that object, it must set up the correct values
@@ -151,13 +178,18 @@ M.availability_ipaddress.form.fillValue = function(value, node) {
value.ipaddresses = this.getValue('ipaddresses', node); value.ipaddresses = this.getValue('ipaddresses', node);
}; };
/**
* FillErrors
* @param {object} errors
* @param {object} node
*/
M.availability_ipaddress.form.fillErrors = function(errors, node) { M.availability_ipaddress.form.fillErrors = function(errors, node) {
"use strict"; "use strict";
var value = {}; var value = {};
this.fillValue(value, node); this.fillValue(value, node);
// Basic ipaddresses checks. // Basic ipaddresses checks.
if (M.availability_ipaddress.validate_ipaddress(value.ipaddresses) === false) { if (M.availability_ipaddress.validateIpaddress(value.ipaddresses) === false) {
errors.push('availability_ipaddress:error_ipaddress'); errors.push('availability_ipaddress:error_ipaddress');
} }
}; };

View File

@@ -7,4 +7,4 @@
"moodle-core_availability-form" "moodle-core_availability-form"
] ]
} }
} }