Skip to content

Commit

Permalink
improving hostname validation
Browse files Browse the repository at this point in the history
  • Loading branch information
douglasgabriel committed Dec 15, 2017
1 parent 9d1fe36 commit af4cd88
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
36 changes: 36 additions & 0 deletions app/assets/javascripts/directives/hostname_validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(function() {
angular.module('ManageIQ').directive('hostnameValidation', directive);

function directive() {
return {
require: 'ngModel',
restrict: 'A',
link: link,
};
function link(_scope, _elem, _attrs, ctrl) {
ctrl.$validators.hostnameValidation = function(_modelValue, viewValue) {
return ! viewValue || isHostname(viewValue) || isIpAddress(viewValue);
};

/**
* Verifies if the informed value is a valid hostname.
*
* @param {string} value - Value to be validated
* @returns {boolean} True if the value is a valid hostname
*/
var isHostname = function(value) {
return /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/.test(value);
};

/**
* Verifies if the informed value is a valid IP (IPV4 or IPV6).
*
* @param {string} value - Value to be validated
* @returns {boolean} True if the value is a valid IP address (IPV4 or IPV6)
*/
var isIpAddress = function(value) {
return /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/.test(value);
};
}
}
})();
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,16 @@
"ng-required" => ng_reqd_hostname.to_s,
"ng-trim" => false,
"detect-spaces" => "",
"hostname-validation" => "",
"checkchange" => "",
"prefix" => prefix.to_s,
"reset-validation-status" => "#{prefix}_auth_status"}
%span.help-block{"ng-show" => "angularForm.#{prefix}_hostname.$error.required"}
= _("Required")
%span.help-block{"ng-show" => "angularForm.#{prefix}_hostname.$error.detectedSpaces"}
= _("Spaces are prohibited")
%span.help-block{"ng-show" => "angularForm.#{prefix}_hostname.$error.hostnameValidation"}
= _("Wrong hostname format")

- detect = "detectClicked({target: '.detect_button'})"
%span
Expand Down
63 changes: 63 additions & 0 deletions spec/javascripts/directives/hostname_validation_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
describe('hostnameValidation initialization', function() {
var $scope;

beforeEach(module('ManageIQ'));
beforeEach(inject(function($compile, $rootScope) {
$scope = $rootScope;
$scope.model = "hostModel";
var element = angular.element(
'<form name="angularForm">' +
'<input type="text" ng-trim=false hostname_validation ng-model="emsCommonModel.hostname" name="hostname"/>' +
'</form>'
);
$compile(element)($scope);
$scope.$digest();
angularForm = $scope.angularForm;
}));

describe('hostname invalid', function() {
it('sets the form to invalid if hostname has protocol', function() {
angularForm.hostname.$setViewValue('http://localhost');
expect(angularForm.hostname.$error.hostnameValidation).toBeDefined();
expect(angularForm.hostname.$valid).toBeFalsy();
expect(angularForm.$invalid).toBeTruthy();
});

it('sets the form to invalid if hostname has path', function() {
angularForm.hostname.$setViewValue('localhost/path');
expect(angularForm.hostname.$error.hostnameValidation).toBeDefined();
expect(angularForm.hostname.$valid).toBeFalsy();
expect(angularForm.$invalid).toBeTruthy();
});

it('sets the form to invalid if hostname has port', function() {
angularForm.hostname.$setViewValue('localhost:4321');
expect(angularForm.hostname.$error.hostnameValidation).toBeDefined();
expect(angularForm.hostname.$valid).toBeFalsy();
expect(angularForm.$invalid).toBeTruthy();
});
});

describe('hostname valid', function() {
it('sets the form to valid if hostname has domain name', function() {
angularForm.hostname.$setViewValue('domain.name');
expect(angularForm.hostname.$error.hostnameValidation).not.toBeDefined();
expect(angularForm.hostname.$valid).toBeTruthy();
expect(angularForm.$invalid).toBeFalsy();
});

it('sets the form to valid if hostname has ipv4', function() {
angularForm.hostname.$setViewValue('10.10.10.10');
expect(angularForm.hostname.$error.hostnameValidation).not.toBeDefined();
expect(angularForm.hostname.$valid).toBeTruthy();
expect(angularForm.$invalid).toBeFalsy();
});

it('sets the form to valid if hostname has ipv6', function() {
angularForm.hostname.$setViewValue('2001:cdba:0000:0000:0000:0000:3257:9652');
expect(angularForm.hostname.$error.hostnameValidation).not.toBeDefined();
expect(angularForm.hostname.$valid).toBeTruthy();
expect(angularForm.$invalid).toBeFalsy();
});
});
});

0 comments on commit af4cd88

Please sign in to comment.