Skip to content
This repository has been archived by the owner on Mar 31, 2024. It is now read-only.

Commit

Permalink
Index name pattern validation directive
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasolson committed Dec 17, 2014
1 parent 69aa107 commit 6c2ac8b
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 1 deletion.
41 changes: 41 additions & 0 deletions src/kibana/directives/validate_index_name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// See https://github.com/elasticsearch/elasticsearch/issues/6736
define(function (require) {
var _ = require('lodash');

require('modules')
.get('kibana')
.directive('validateIndexName', function () {
return {
restrict: 'A',
require: 'ngModel',
scope: {
'ngModel': '='
},
link: function ($scope, elem, attr, ngModel) {
var illegalCharacters = ['\\', '/', '?', '"', '<', '>', '|', ' ', ','];
var isValid = function (input) {
if (input == null || input === '' || input === '.' || input === '..') return false;

var match = _.find(illegalCharacters, function (character) {
return input.indexOf(character) >= 0;
});
return !match;
};

// From User
ngModel.$parsers.unshift(function (value) {
var valid = isValid(value);
ngModel.$setValidity('indexNameInput', valid);
return valid ? value : undefined;
});

// To user
ngModel.$formatters.unshift(function (value) {
ngModel.$setValidity('indexNameInput', isValid(value));
return value;
});

}
};
});
});
5 changes: 4 additions & 1 deletion src/kibana/plugins/settings/sections/indices/_create.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ <h1>Configure an index pattern</h1>
ng-model="index.name"
ng-attr-placeholder="{{index.defaultName}}"
ng-model-options="{ updateOn: 'default blur', debounce: {'default': 2500, 'blur': 0} }"
validate-index-name
name="name"
required
type="text"
class="form-control">
Expand Down Expand Up @@ -116,7 +118,8 @@ <h1>Configure an index pattern</h1>
ng-class="index.fetchFieldsError ? 'btn-default' : 'btn-success'"
type="submit"
class="btn">
{{index.fetchFieldsError || "Create" }}
<span ng-hide="form.name.$error.indexNameInput">{{index.fetchFieldsError || "Create" }}</span>
<span ng-show="form.name.$error.indexNameInput">Invalid index name pattern.</span>
</button>
</form>
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/kibana/plugins/settings/sections/indices/_create.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ define(function (require) {
var moment = require('moment');
var errors = require('errors');

require('directives/validate_index_name');

require('routes')
.when('/settings/indices/', {
template: require('text!plugins/settings/sections/indices/_create.html')
Expand Down
137 changes: 137 additions & 0 deletions test/unit/specs/directives/validate_index_name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
define(function (require) {
var angular = require('angular');

// Load the kibana app dependencies.
require('directives/validate_index_name');

describe('Validate index name directive', function () {
var $compile, $rootScope;
var html = '<input type="text" ng-model="indexName" validate-index-name />';

beforeEach(module('kibana'));

beforeEach(inject(function (_$compile_, _$rootScope_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
}));

it('should not accept null index name patterns', function () {
$rootScope.indexName = null;
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept undefined index name patterns', function () {
$rootScope.indexName = undefined;
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept empty index name patterns', function () {
$rootScope.indexName = '';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept . as an index name pattern', function () {
$rootScope.indexName = '.';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept .. as an index name pattern', function () {
$rootScope.indexName = '..';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept \\ in an index name pattern', function () {
$rootScope.indexName = 'foo\\bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept / in an index name pattern', function () {
$rootScope.indexName = 'foo/bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept ? in an index name pattern', function () {
$rootScope.indexName = 'foo?bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept " in an index name pattern', function () {
$rootScope.indexName = 'foo"bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept < in an index name pattern', function () {
$rootScope.indexName = 'foo<bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept > in an index name pattern', function () {
$rootScope.indexName = 'foo>bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept | in an index name pattern', function () {
$rootScope.indexName = 'foo|bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept spaces in an index name pattern', function () {
$rootScope.indexName = 'foo bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should not accept , in an index name pattern', function () {
$rootScope.indexName = 'foo,bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.be.ok();
});

it('should accept a valid index name pattern', function () {
$rootScope.indexName = 'foo.bar';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.not.be.ok();
});

it('should accept * in an index name pattern', function () {
$rootScope.indexName = 'foo.*';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.not.be.ok();
});

it('should accept [] in an index name pattern', function () {
$rootScope.indexName = '[foo]-YYYY.MM.DD';
var element = $compile(html)($rootScope);
$rootScope.$digest();
expect(element.hasClass('ng-invalid')).to.not.be.ok();
});
});
});

0 comments on commit 6c2ac8b

Please sign in to comment.